Index: lib/Target/Sparc/Disassembler/SparcDisassembler.cpp =================================================================== --- lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -31,6 +31,11 @@ /// A disassembler class for Sparc. class SparcDisassembler : public MCDisassembler { + DecodeStatus getInstructionREX(MCInst &Instr, uint64_t &Size, + ArrayRef Bytes, uint64_t Address, + raw_ostream &VStream, + raw_ostream &CStream) const; + public: SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) : MCDisassembler(STI, Ctx) {} @@ -141,7 +146,6 @@ SP::C28, SP::C29, SP::C30, SP::C31 }; - static const uint16_t CPPairDecoderTable[] = { SP::C0_C1, SP::C2_C3, SP::C4_C5, SP::C6_C7, SP::C8_C9, SP::C10_C11, SP::C12_C13, SP::C14_C15, @@ -149,6 +153,66 @@ SP::C24_C25, SP::C26_C27, SP::C28_C29, SP::C30_C31 }; +static const unsigned RexIntRegDecoderTable[] = { + SP::O0, SP::O1, SP::O2, SP::O3, SP::L4, SP::L5, SP::L6, SP::L7, + SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5, SP::I6, SP::I7, + SP::L0, SP::L1, SP::L2, SP::L3, SP::O4, SP::O5, SP::O6, SP::O7, + SP::G0, SP::G1, SP::G2, SP::G3, SP::G4, SP::G5, SP::G6, SP::G7}; + +static const uint16_t RexIntPairDecoderTable[] = { + SP::O0_O1, SP::O2_O3, SP::L4_L5, SP::L6_L7, SP::I0_I1, SP::I2_I3, + SP::I4_I5, SP::I6_I7, SP::L0_L1, SP::L2_L3, SP::O4_O5, SP::O6_O7, + SP::G0_G1, SP::G2_G3, SP::G4_G5, SP::G6_G7}; + +static const unsigned RexFPRegDecoderTable[] = { + SP::F16, SP::F17, SP::F18, SP::F19, SP::F12, SP::F13, SP::F14, SP::F15, + SP::F0, SP::F1, SP::F2, SP::F3, SP::F4, SP::F5, SP::F6, SP::F7}; + +static const unsigned RexDFPRegDecoderTable[] = { + SP::D8, SP::D9, SP::D6, SP::D7, SP::D0, SP::D1, SP::D2, SP::D3}; + +static DecodeStatus DecodeRexIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + unsigned Reg = RexIntRegDecoderTable[RegNo]; + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeRexIntPairRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder) { + RegNo >>= 1; + if (RegNo > 15) + return MCDisassembler::Fail; + unsigned Reg = RexIntPairDecoderTable[RegNo]; + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeRexFPRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 15) + return MCDisassembler::Fail; + unsigned Reg = RexFPRegDecoderTable[RegNo]; + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeRexDFPRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder) { + RegNo >>= 1; + if (RegNo > 7) + return MCDisassembler::Fail; + unsigned Reg = RexDFPRegDecoderTable[RegNo]; + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -301,10 +365,18 @@ uint64_t Address, const void *Decoder); static DecodeStatus DecodeStoreCPPair(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeShortRexBranch(MCInst &MI, unsigned Offset, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodeLongRexBranch(MCInst &MI, unsigned Offset, + uint64_t Address, const void *Decoder); static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeSIMM21(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder); static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeSIMM5(MCInst &Inst, unsigned insn, uint64_t Address, + const void *Decoder); static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder); static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, @@ -313,6 +385,8 @@ const void *Decoder); static DecodeStatus DecodeTRAP(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeADDRfi(MCInst &MI, unsigned insn, uint64_t Address, + const void *Decoder); #include "SparcGenDisassemblerTables.inc" @@ -335,6 +409,71 @@ return MCDisassembler::Success; } +DecodeStatus SparcDisassembler::getInstructionREX(MCInst &Instr, uint64_t &Size, + ArrayRef Bytes, + uint64_t Address, + raw_ostream &VStream, + raw_ostream &CStream) const { + DecodeStatus Result; + uint64_t Insn; + + if (Bytes.size() < 2) { + Size = 0; + return MCDisassembler::Fail; + } + + Insn = (Bytes[1] << 0) | (Bytes[0] << 8); + + uint32_t rop = Insn >> 14; + int bsz = (Insn >> 9) & 1; + int rop3 = (Insn >> 5) & 0xF; + + Size = 2; + if (rop == 0 && bsz == 1) + Size = 4; + else if (rop == 1) + Size = 4; + else if ((rop == 2 || rop == 3) && (rop3 == 7)) + Size = 4; + else if ((rop == 2 || rop == 3) && (rop3 == 15)) + Size = 6; + + if (Bytes.size() < Size) { + Size = 0; + return MCDisassembler::Fail; + } + + if (Size == 2) { + Result = decodeInstruction(DecoderTableSparcRex16, Instr, Insn, Address, + this, STI); + } else if (Size == 4) { + Insn = + (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24); + + bool isCall = (Insn >> 30) == 1; + + if (isCall) { + Result = decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, + this, STI); + } else { + Result = decodeInstruction(DecoderTableSparcRex32, Instr, Insn, Address, + this, STI); + } + } else if (Size == 6) { + Insn = (Bytes[5] << 0) | (Bytes[4] << 8) | (Bytes[3] << 16) | + (Bytes[2] << 24) | ((uint64_t)Bytes[1] << 32) | + ((uint64_t)Bytes[0] << 40); + Result = decodeInstruction(DecoderTableSparcRex48, Instr, Insn, Address, + this, STI); + } else + llvm_unreachable("Unknown instruction size"); + + if (Result == MCDisassembler::Fail) { + return MCDisassembler::Fail; + } + return MCDisassembler::Success; +} + DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef Bytes, uint64_t Address, @@ -342,8 +481,12 @@ raw_ostream &CStream) const { uint32_t Insn; bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian(); - DecodeStatus Result = - readInstruction32(Bytes, Address, Size, Insn, isLittleEndian); + DecodeStatus Result; + + if (STI.getFeatureBits()[Sparc::FeatureREX]) + return getInstructionREX(Instr, Size, Bytes, Address, VStream, CStream); + + Result = readInstruction32(Bytes, Address, Size, Insn, isLittleEndian); if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; @@ -515,6 +658,25 @@ Offset, Width); } +static DecodeStatus DecodeShortRexBranch(MCInst &MI, unsigned Offset, + uint64_t Address, + const void *Decoder) { + + int32_t BranchOffset = SignExtend32<8>(Offset) * 2; + + MI.addOperand(MCOperand::createImm(BranchOffset)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeLongRexBranch(MCInst &MI, unsigned Offset, + uint64_t Address, const void *Decoder) { + + int32_t BranchOffset = SignExtend32<24>(Offset) * 2; + + MI.addOperand(MCOperand::createImm(BranchOffset)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, uint64_t Address, const void *Decoder) { unsigned tgt = fieldFromInstruction(insn, 0, 30); @@ -525,6 +687,13 @@ return MCDisassembler::Success; } +static DecodeStatus DecodeSIMM21(MCInst &MI, unsigned insn, uint64_t Address, + const void *Decoder) { + unsigned tgt = SignExtend32<21>(fieldFromInstruction(insn, 0, 21)); + MI.addOperand(MCOperand::createImm(tgt)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, uint64_t Address, const void *Decoder) { unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); @@ -532,6 +701,25 @@ return MCDisassembler::Success; } +static DecodeStatus DecodeSIMM5(MCInst &MI, unsigned insn, uint64_t Address, + const void *Decoder) { + unsigned tgt = SignExtend32<5>(fieldFromInstruction(insn, 0, 5)); + MI.addOperand(MCOperand::createImm(tgt)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeADDRfi(MCInst &MI, unsigned insn, uint64_t Address, + const void *Decoder) { + unsigned regs[4] = {SP::I6, SP::O6, SP::I0, SP::O0}; + unsigned rs = fieldFromInstruction(insn, 5, 2); + unsigned imm = fieldFromInstruction(insn, 0, 5) << 2; + + MI.addOperand(MCOperand::createReg(regs[rs])); + MI.addOperand(MCOperand::createImm(imm)); + + return MCDisassembler::Success; +} + static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address, const void *Decoder) { Index: lib/Target/Sparc/SparcInstrRex.td =================================================================== --- lib/Target/Sparc/SparcInstrRex.td +++ lib/Target/Sparc/SparcInstrRex.td @@ -159,30 +159,35 @@ def IntRegsAsRex : Operand { let MIOperandInfo = (ops IntRegs); let EncoderMethod = "getRexIntRegEncoding"; + let DecoderMethod = "DecodeRexIntRegsRegisterClass"; let ParserMatchClass = IntRegAsRexAsmOperand; } def RexIntRegsOp : Operand { let MIOperandInfo = (ops RexIntRegs); let EncoderMethod = "getRexIntRegEncoding"; + let DecoderMethod = "DecodeRexIntRegsRegisterClass"; let ParserMatchClass = RexIntRegAsmOperand; } def RexIntPairOp : Operand { let MIOperandInfo = (ops RexIntPair); let EncoderMethod = "getRexIntRegEncoding"; + let DecoderMethod = "DecodeRexIntPairRegisterClass"; let ParserMatchClass = RexIntPairAsmOperand; } def RexFPRegsOp : Operand { let MIOperandInfo = (ops RexFPRegs); let EncoderMethod = "getRexFPRegEncoding"; + let DecoderMethod = "DecodeRexFPRegsRegisterClass"; let ParserMatchClass = RexFPRegAsmOperand; } def RexDFPRegsOp : Operand { let MIOperandInfo = (ops RexDFPRegs); let EncoderMethod = "getRexFPRegEncoding"; + let DecoderMethod = "DecodeRexDFPRegsRegisterClass"; let ParserMatchClass = RexDFPRegAsmOperand; } @@ -190,22 +195,33 @@ let MIOperandInfo = (ops RexIntRegsOp:$rs); let ParserMatchClass = RexMEMREXrAsmOperand; let EncoderMethod = "getRexIntRegEncoding"; + let DecoderMethod = "DecodeRexIntRegsRegisterClass"; } class RegImmOperand : Operand { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops RexIntRegsOp:$rs, i32imm:$imm5); let EncoderMethod = "getADDRfiOpValue"; + let DecoderMethod = "DecodeADDRfi"; } def ADDRfi : RegImmOperand { let ParserMatchClass = RexMEMfiAsmOperand; } def ADDRffi : RegImmOperand { let ParserMatchClass = RexMEMffiAsmOperand; } -def Imm3Op : Operand { let ParserMatchClass = Imm3AsmOperand; } -def Imm5Op : Operand { let ParserMatchClass = Imm5AsmOperand; } -def SImm5Op : Operand { let ParserMatchClass = SImm5AsmOperand; } -def NImm13Op : Operand { let ParserMatchClass = NImm13AsmOperand; } -def SImm21Op : Operand { let ParserMatchClass = SImm21AsmOperand; } +def Imm3Op : Operand { let ParserMatchClass = Imm3AsmOperand; } +def Imm5Op : Operand { let ParserMatchClass = Imm5AsmOperand; } +def SImm5Op : Operand { + let ParserMatchClass = SImm5AsmOperand; + let DecoderMethod = "DecodeSIMM5"; +} +def NImm13Op : Operand { + let ParserMatchClass = NImm13AsmOperand; + let DecoderMethod = "DecodeSIMM13"; +} +def SImm21Op : Operand { + let ParserMatchClass = SImm21AsmOperand; + let DecoderMethod = "DecodeSIMM21"; +} def Imm32Op : Operand { let EncoderMethod = "getImm32OpValue"; } def Imm32DOp : Operand { let EncoderMethod = "getImm32DispOpValue"; } @@ -230,6 +246,7 @@ // Section 6.3.1 - Branch on Integer Condition Codes - Short def brtarget8 : Operand { + let DecoderMethod = "DecodeShortRexBranch"; let EncoderMethod = "getRexShortBranchTargetOpValue"; let ParserMatchClass = BrTarget8AsmOperand; } @@ -513,6 +530,7 @@ // Section 6.4.1 - Branch on integer condition codes - Long def brtarget24 : Operand { + let DecoderMethod = "DecodeLongRexBranch"; let EncoderMethod = "getRexLongBranchTargetOpValue"; let ParserMatchClass = BrTarget24AsmOperand; } Index: test/MC/Disassembler/Sparc/rex-instructions.txt =================================================================== --- /dev/null +++ test/MC/Disassembler/Sparc/rex-instructions.txt @@ -0,0 +1,397 @@ +# RUN: llvm-mc --disassemble %s -triple=sparc-unknown-linux -mattr=rex | FileCheck %s + +# Section 6.3.1 - Branch on Integer Condition Codes - Short + +# CHECK: rbleu 10 +0x10 0x05 +# CHECK: rbleu -10 +0x10 0xfb +# CHECK: rbleu 254 +0x10 0x7f +# CHECK: rbleu -256 +0x10 0x80 +# CHECK: rba 10 +0x20 0x05 +# CHECK: rbn 10 +0x00 0x05 +# CHECK: rbne 10 +0x24 0x05 +# CHECK: rbe 10 +0x04 0x05 +# CHECK: rbg 10 +0x28 0x05 +# CHECK: rble 10 +0x08 0x05 +# CHECK: rbge 10 +0x2c 0x05 +# CHECK: rbl 10 +0x0c 0x05 +# CHECK: rbgu 10 +0x30 0x05 +# CHECK: rbleu 10 +0x10 0x05 +# CHECK: rbcc 10 +0x34 0x05 +# CHECK: rbcs 10 +0x14 0x05 +# CHECK: rbpos 10 +0x38 0x05 +# CHECK: rbneg 10 +0x18 0x05 +# CHECK: rbvc 10 +0x3c 0x05 +# CHECK: rbvs 10 +0x1c 0x05 + +# Section 6.3.2 - Branch on Floating-Point Condition Codes - Short + +# CHECK: rfbule 10 +0x39 0x05 +# CHECK: rfbule -10 +0x39 0xfb +# CHECK: rfbule 254 +0x39 0x7f +# CHECK: rfbule -256 +0x39 0x80 +# CHECK: rfba 10 +0x21 0x05 +# CHECK: rfbn 10 +0x01 0x05 +# CHECK: rfbu 10 +0x1d 0x05 +# CHECK: rfbg 10 +0x19 0x05 +# CHECK: rfbug 10 +0x15 0x05 +# CHECK: rfbl 10 +0x11 0x05 +# CHECK: rfbul 10 +0x0d 0x05 +# CHECK: rfblg 10 +0x09 0x05 +# CHECK: rfbne 10 +0x05 0x05 +# CHECK: rfbe 10 +0x25 0x05 +# CHECK: rfbue 10 +0x29 0x05 +# CHECK: rfbge 10 +0x2d 0x05 +# CHECK: rfbuge 10 +0x31 0x05 +# CHECK: rfble 10 +0x35 0x05 +# CHECK: rfbo 10 +0x3d 0x05 + +# Section 6.3.3 - Arithmetic operations - Accumulator with register + +# CHECK: radd %o0, %i7 +0xbc 0x00 +# CHECK: raddcc %o1, %fp +0xb8 0x11 +# CHECK: rsub %o2, %i5 +0xb4 0x22 +# CHECK: rsubcc %o3, %i4 +0xb0 0x33 +# CHECK: rand %l4, %i3 +0xac 0x44 +# CHECK: randcc %l5, %i2 +0xa8 0x55 +# CHECK: randn %l6, %i1 +0xa5 0x46 +# CHECK: randncc %l7, %i0 +0xa1 0x57 +# CHECK: ror %i0, %l7 +0x9c 0x88 +# CHECK: rorcc %i1, %l6 +0x98 0x99 +# CHECK: rorn %i2, %l5 +0x95 0x8a +# CHECK: rorncc %i3, %l4 +0x91 0x9b +# CHECK: rxor %i4, %o3 +0x8c 0xcc +# CHECK: rxorcc %i5, %o2 +0x88 0xdd +# CHECK: rsll %fp, %o1 +0x85 0x6e +# CHECK: rsrl %i7, %o0 +0x81 0xaf + +# Section 6.3.4 - Arithmetic operations - Accumulator with immediate + +# CHECK: raddcc 10, %l4 +0x92 0x0a +# CHECK: raddcc 15, %l4 +0x92 0x0f +# CHECK: raddcc -16, %l4 +0x92 0x10 +# CHECK: rsll 4, %l5 +0x97 0x64 +# CHECK: rsll 31, %l5 +0x97 0x7f +# CHECK: rsrl 2, %l6 +0x9b 0xa2 + +# Section 6.3.5 - Comparison with register + +# CHECK: rcmp %l6, %o1 +0x99 0x71 + +# Section 6.3.6 - Comparison with immediate + +# CHECK: rcmp %l4, 10 +0x93 0x0a + +# Section 6.3.7 - Constant assignment + +# CHECK: rset5 10, %o1 +0x86 0x2a +# CHECK: rone 4, %o1 +0x86 0xa4 + +# Section 6.3.8 - Bit-mask operations + +# CHECK: rsetbit 13, %o3 +0x8e 0x8d +# CHECK: rclrbit 13, %o3 +0x8f 0x4d +# CHECK: rinvbit 13, %o3 +0x8e 0xcd +# CHECK: rmasklo 13, %o3 +0x8e 0x4d +# CHECK: rtstbit 13, %o3 +0x8e 0x6d + +# Section 6.3.9 - Register to register copy + +# CHECK: rmov %o2, %g3 +0xad 0x22 + +# Section 6.3.10 - Negation + +# CHECK: rneg %o3 +0x8f 0xc4 +# CHECK: rnot %o3 +0x8f 0xc5 + +# Section 6.3.11 - Return instructions + +# CHECK: rretrest +0x83 0xc0 +# CHECK: rretl +0x83 0xc1 + +# Section 6.3.12 - Load/Store - 8/16/32/64 - one register + +# CHECK: rld [%o3], %l4 +0xd0 0x03 +# CHECK: rldub [%o3], %l4 +0xd0 0x43 +# CHECK: rlduh [%o3], %l4 +0xd0 0x83 +# CHECK: rldd [%o3], %l4 +0xd0 0xc3 +# CHECK: rldf [%o3], %f1 +0xe4 0x23 +# CHECK: rlddf [%o3], %f2 +0xe8 0xa3 + +# CHECK: rst %l4, [%o3] +0xd1 0x03 +# CHECK: rstb %l4, [%o3] +0xd1 0x43 +# CHECK: rsth %l4, [%o3] +0xd1 0x83 +# CHECK: rstd %l4, [%o3] +0xd1 0xc3 +# CHECK: rstf %f1, [%o3] +0xe5 0x23 +# CHECK: rstdf %f4, [%l4] +0xf1 0xa4 + +# Section 6.3.13 - Load/Store - 8/16/32/64 - fixed register plus immediate + +# CHECK: rld [%i0+124], %l4 +0xd2 0x9f +# CHECK: rld [%i0+40], %l4 +0xd2 0x8a +# CHECK: rld [%o0+40], %l4 +0xd2 0xca +# CHECK: rld [%fp+40], %l4 +0xd2 0x0a +# CHECK: rld [%sp+40], %l4 +0xd2 0x4a +# CHECK: rldf [%i0+40], %f1 +0xe6 0xaa +# CHECK: rldf [%fp+40], %f1 +0xe6 0x2a +# CHECK: rldf [%sp+40], %f1 +0xe6 0x6a + +# CHECK: rst %l4, [%i0+40] +0xd3 0x8a +# CHECK: rst %l4, [%o0+40] +0xd3 0xca +# CHECK: rst %l4, [%fp+40] +0xd3 0x0a +# CHECK: rst %l4, [%sp+40] +0xd3 0x4a +# CHECK: rstf %f1, [%i0+40] +0xe7 0xaa +# CHECK: rstf %f1, [%fp+40] +0xe7 0x2a +# CHECK: rstf %f1, [%sp+40] +0xe7 0x6a + +# Section 6.3.14 - Load/Store - 8/16/32/64 - one register - auto-incrementing + +# CHECK: rldinc [%o3], %l4 +0xd0 0x13 +# CHECK: rldubinc [%o3], %l4 +0xd0 0x53 +# CHECK: rlduhinc [%o3], %l4 +0xd0 0x93 +# CHECK: rlddinc [%o3], %l4 +0xd0 0xd3 +# CHECK: rldfinc [%o3], %f1 +0xe4 0x33 +# CHECK: rlddfinc [%o3], %f2 +0xe8 0xb3 + +# CHECK: rstinc %l4, [%o3] +0xd1 0x13 +# CHECK: rstbinc %l4, [%o3] +0xd1 0x53 +# CHECK: rsthinc %l4, [%o3] +0xd1 0x93 +# CHECK: rstdinc %l4, [%o3] +0xd1 0xd3 +# CHECK: rstfinc %f1, [%o3] +0xe5 0x33 +# CHECK: rstdfinc %f4, [%l4] +0xf1 0xb4 + +# Section 6.3.15 - Miscellaneous operations - no source operands + +# CHECK: rpush %l4 +0x93 0xc2 + +# CHECK: rpop %l4 +0x93 0xc3 + +# CHECK: rta 5 +0x97 0xc6 + +# CHECK: rleave +0x83 0xc7 + +# CHECK: getpc %l4 +0x93 0xc9 + +# Section 6.4.1 - Branch on integer condition codes - long + +# CHECK: rbleu,l 50000 +0x12 0xa8 0x00 0x61 +# CHECK: rbleu,l -50000 +0x12 0x58 0xff 0x9e +# CHECK: rba,l 50000 +0x22 0xa8 0x00 0x61 +# CHECK: rbn,l 50000 +0x02 0xa8 0x00 0x61 +# CHECK: rbne,l 50000 +0x26 0xa8 0x00 0x61 +# CHECK: rbe,l 50000 +0x06 0xa8 0x00 0x61 +# CHECK: rbg,l 50000 +0x2a 0xa8 0x00 0x61 +# CHECK: rble,l 50000 +0x0a 0xa8 0x00 0x61 +# CHECK: rbge,l 50000 +0x2e 0xa8 0x00 0x61 +# CHECK: rbl,l 50000 +0x0e 0xa8 0x00 0x61 +# CHECK: rbgu,l 50000 +0x32 0xa8 0x00 0x61 +# CHECK: rbleu,l 50000 +0x12 0xa8 0x00 0x61 +# CHECK: rbcc,l 50000 +0x36 0xa8 0x00 0x61 +# CHECK: rbcs,l 50000 +0x16 0xa8 0x00 0x61 +# CHECK: rbpos,l 50000 +0x3a 0xa8 0x00 0x61 +# CHECK: rbneg,l 50000 +0x1a 0xa8 0x00 0x61 +# CHECK: rbvc,l 50000 +0x3e 0xa8 0x00 0x61 +# CHECK: rbvs,l 50000 +0x1e 0xa8 0x00 0x61 + +# Section 6.4.2 - Branch on floating-point condition codes - long + +# CHECK: rfbule,l 50000 +0x3b 0xa8 0x00 0x61 +# CHECK: rfbule,l -50000 +0x3b 0x58 0xff 0x9e +# CHECK: rfba,l 50000 +0x23 0xa8 0x00 0x61 +# CHECK: rfbn,l 50000 +0x03 0xa8 0x00 0x61 +# CHECK: rfbu,l 50000 +0x1f 0xa8 0x00 0x61 +# CHECK: rfbg,l 50000 +0x1b 0xa8 0x00 0x61 +# CHECK: rfbug,l 50000 +0x17 0xa8 0x00 0x61 +# CHECK: rfbl,l 50000 +0x13 0xa8 0x00 0x61 +# CHECK: rfbul,l 50000 +0x0f 0xa8 0x00 0x61 +# CHECK: rfblg,l 50000 +0x0b 0xa8 0x00 0x61 +# CHECK: rfbne,l 50000 +0x07 0xa8 0x00 0x61 +# CHECK: rfbe,l 50000 +0x27 0xa8 0x00 0x61 +# CHECK: rfbue,l 50000 +0x2b 0xa8 0x00 0x61 +# CHECK: rfbge,l 50000 +0x2f 0xa8 0x00 0x61 +# CHECK: rfbuge,l 5000 +0x33 0xa8 0x00 0x61 +# CHECK: rfble,l 50000 +0x37 0xa8 0x00 0x61 +# CHECK: rfbo,l 50000 +0x3f 0xa8 0x00 0x61 + +# Section 6.4.3 - Call and link + +# CHECK: call 50000 +0x40 0x00 0x30 0xd4 + +# Section 6.4.4 - Constant assignment + +# CHECK: rset21 50000, %l4 +0x92 0xf0 0x06 0x1a + +# Section 6.4.5 - Generic format 3 SPARC operation + +# Section 6.4.6 - Floating-point operations + +# Section 6.5.1 - Set 32-bit constant + +# CHECK: rset32 50000, %l4 +0x93 0xe8 0x00 0x00 0xc3 0x50 + +# CHECK: rset32pc 50000, %l4 +0x93 0xe9 0x00 0x00 0xc3 0x50 + +# Section 6.5.2 - Load from 32-bit address + +# CHECK: rld32 [50000], %l4 +0x93 0xea 0x00 0x00 0xc3 0x50 + +# CHECK: rld32pc [50000], %l4 +0x93 0xeb 0x00 0x00 0xc3 0x50 Index: test/MC/Disassembler/Sparc/rex-sparc-instructions.txt =================================================================== --- /dev/null +++ test/MC/Disassembler/Sparc/rex-sparc-instructions.txt @@ -0,0 +1,10 @@ +# RUN: llvm-mc --disassemble %s -triple=sparc-v8-linux | FileCheck %s + +# Section 6.2.1 - SAVEREX and ADDREX + +# CHECK: saverex %sp, -20, %sp +0x9d 0xe3 0x9f 0xec + +# CHECK: addrex %sp, -20, %sp +0x9c 0x03 0x9f 0xec +