From 099001979fe82a069d5572dffea472b339878c75 Mon Sep 17 00:00:00 2001 From: James Y Knight Date: Sun, 20 Nov 2022 20:41:42 -0500 Subject: [PATCH] [SPARC] Simplify instruction decoder. After https://reviews.llvm.org/D137653 named sub-operands can be used in the auto-generated instruction decoders. This allows the auto-generated decoders to work properly, so all the hand-coded decoders in the sparc target can be removed. In some instances, a manually-written decoder had not been implemented for an instruction, and thus that instruction was not decoded properly. These have been fixed (and tests added). Differential Revision: https://reviews.llvm.org/D137727 --- .../Sparc/Disassembler/SparcDisassembler.cpp | 357 +-------------------- llvm/lib/Target/Sparc/SparcInstr64Bit.td | 9 +- llvm/lib/Target/Sparc/SparcInstrInfo.td | 180 +++++------ llvm/test/MC/Disassembler/Sparc/sparc-coproc.txt | 85 +++++ llvm/test/MC/Disassembler/Sparc/sparc-mem.txt | 117 +++++++ .../Disassembler/Sparc/sparc-special-registers.txt | 6 - llvm/test/MC/Disassembler/Sparc/sparc-v9.txt | 6 + llvm/test/MC/Disassembler/Sparc/sparc.txt | 3 + 8 files changed, 305 insertions(+), 458 deletions(-) create mode 100644 llvm/test/MC/Disassembler/Sparc/sparc-coproc.txt diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index 6a132ed..496c08f 100644 --- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -155,11 +155,15 @@ static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder) { - if (RegNo > 31) - return MCDisassembler::Fail; - unsigned Reg = IntRegDecoderTable[RegNo]; - Inst.addOperand(MCOperand::createReg(Reg)); - return MCDisassembler::Success; + return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder); +} + +// This is used for the type "ptr_rc", which is either IntRegs or I64Regs +// depending on SparcRegisterInfo::getPointerRegClass. +static DecodeStatus DecodePointerLikeRegClass0(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const MCDisassembler *Decoder) { + return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder); } static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, unsigned RegNo, @@ -195,9 +199,9 @@ static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, unsigned RegNo, return MCDisassembler::Success; } -static DecodeStatus DecodeCPRegsRegisterClass(MCInst &Inst, unsigned RegNo, - uint64_t Address, - const MCDisassembler *Decoder) { +static DecodeStatus +DecodeCoprocRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, + const MCDisassembler *Decoder) { if (RegNo > 31) return MCDisassembler::Fail; unsigned Reg = CPRegDecoderTable[RegNo]; @@ -248,9 +252,9 @@ static DecodeStatus DecodeIntPairRegisterClass(MCInst &Inst, unsigned RegNo, return S; } -static DecodeStatus DecodeCPPairRegisterClass(MCInst &Inst, unsigned RegNo, - uint64_t Address, - const MCDisassembler *Decoder) { +static DecodeStatus +DecodeCoprocPairRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, + const MCDisassembler *Decoder) { if (RegNo > 31) return MCDisassembler::Fail; @@ -259,56 +263,10 @@ static DecodeStatus DecodeCPPairRegisterClass(MCInst &Inst, unsigned RegNo, return MCDisassembler::Success; } -static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeLoadIntPair(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeLoadCP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeLoadCPPair(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeStoreIntPair(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeStoreCP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeStoreCPPair(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder); static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, uint64_t Address, const MCDisassembler *Decoder); static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, uint64_t Address, const MCDisassembler *Decoder); -static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeTRAP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder); -static DecodeStatus DecodeFIXMEInstruction(MCInst &MI, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder); #include "SparcGenDisassemblerTables.inc" @@ -366,147 +324,6 @@ DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, return MCDisassembler::Fail; } -typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder); - -static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder, bool isLoad, - DecodeFunc DecodeRD) { - unsigned rd = fieldFromInstruction(insn, 25, 5); - unsigned rs1 = fieldFromInstruction(insn, 14, 5); - bool isImm = fieldFromInstruction(insn, 13, 1); - bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field) - unsigned asi = fieldFromInstruction(insn, 5, 8); - unsigned rs2 = 0; - unsigned simm13 = 0; - if (isImm) - simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); - else - rs2 = fieldFromInstruction(insn, 0, 5); - - DecodeStatus status; - if (isLoad) { - status = DecodeRD(MI, rd, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - } - - // Decode rs1. - status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - - // Decode imm|rs2. - if (isImm) - MI.addOperand(MCOperand::createImm(simm13)); - else { - status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - } - - if (hasAsi) - MI.addOperand(MCOperand::createImm(asi)); - - if (!isLoad) { - status = DecodeRD(MI, rd, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - } - return MCDisassembler::Success; -} - -static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, true, - DecodeIntRegsRegisterClass); -} - -static DecodeStatus DecodeLoadIntPair(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, true, - DecodeIntPairRegisterClass); -} - -static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, true, - DecodeFPRegsRegisterClass); -} - -static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, true, - DecodeDFPRegsRegisterClass); -} - -static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, true, - DecodeQFPRegsRegisterClass); -} - -static DecodeStatus DecodeLoadCP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, true, - DecodeCPRegsRegisterClass); -} - -static DecodeStatus DecodeLoadCPPair(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, true, - DecodeCPPairRegisterClass); -} - -static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, false, - DecodeIntRegsRegisterClass); -} - -static DecodeStatus DecodeStoreIntPair(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, false, - DecodeIntPairRegisterClass); -} - -static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, false, - DecodeFPRegsRegisterClass); -} - -static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, false, - DecodeDFPRegsRegisterClass); -} - -static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, false, - DecodeQFPRegsRegisterClass); -} - -static DecodeStatus DecodeStoreCP(MCInst &Inst, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, false, - DecodeCPRegsRegisterClass); -} - -static DecodeStatus DecodeStoreCPPair(MCInst &Inst, unsigned insn, - uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeMem(Inst, insn, Address, Decoder, false, - DecodeCPPairRegisterClass); -} - static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, uint64_t Address, uint64_t Offset, uint64_t Width, MCInst &MI, @@ -531,147 +348,3 @@ static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, uint64_t Address, MI.addOperand(MCOperand::createImm(tgt)); return MCDisassembler::Success; } - -static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder) { - - unsigned rd = fieldFromInstruction(insn, 25, 5); - unsigned rs1 = fieldFromInstruction(insn, 14, 5); - unsigned isImm = fieldFromInstruction(insn, 13, 1); - unsigned rs2 = 0; - unsigned simm13 = 0; - if (isImm) - simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); - else - rs2 = fieldFromInstruction(insn, 0, 5); - - // Decode RD. - DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - - // Decode RS1. - status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - - // Decode RS1 | SIMM13. - if (isImm) - MI.addOperand(MCOperand::createImm(simm13)); - else { - status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - } - return MCDisassembler::Success; -} - -static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder) { - - unsigned rs1 = fieldFromInstruction(insn, 14, 5); - unsigned isImm = fieldFromInstruction(insn, 13, 1); - unsigned rs2 = 0; - unsigned simm13 = 0; - if (isImm) - simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); - else - rs2 = fieldFromInstruction(insn, 0, 5); - - // Decode RS1. - DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - - // Decode RS2 | SIMM13. - if (isImm) - MI.addOperand(MCOperand::createImm(simm13)); - else { - status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - } - return MCDisassembler::Success; -} - -// This instruction does not have a working decoder, and needs to be -// fixed. This "fixme" function was introduced to keep the backend compiling, -// while making changes to tablegen code. -static DecodeStatus DecodeFIXMEInstruction(MCInst &Inst, unsigned Insn, - uint64_t Address, - const MCDisassembler *Decoder) { - return MCDisassembler::Fail; -} - -static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder) { - - unsigned rd = fieldFromInstruction(insn, 25, 5); - unsigned rs1 = fieldFromInstruction(insn, 14, 5); - unsigned isImm = fieldFromInstruction(insn, 13, 1); - bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field) - unsigned asi = fieldFromInstruction(insn, 5, 8); - unsigned rs2 = 0; - unsigned simm13 = 0; - if (isImm) - simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); - else - rs2 = fieldFromInstruction(insn, 0, 5); - - // Decode RD. - DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - - // Decode RS1. - status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - - // Decode RS1 | SIMM13. - if (isImm) - MI.addOperand(MCOperand::createImm(simm13)); - else { - status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - } - - if (hasAsi) - MI.addOperand(MCOperand::createImm(asi)); - - return MCDisassembler::Success; -} - -static DecodeStatus DecodeTRAP(MCInst &MI, unsigned insn, uint64_t Address, - const MCDisassembler *Decoder) { - - unsigned rs1 = fieldFromInstruction(insn, 14, 5); - unsigned isImm = fieldFromInstruction(insn, 13, 1); - unsigned cc =fieldFromInstruction(insn, 25, 4); - unsigned rs2 = 0; - unsigned imm7 = 0; - if (isImm) - imm7 = fieldFromInstruction(insn, 0, 7); - else - rs2 = fieldFromInstruction(insn, 0, 5); - - // Decode RS1. - DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - - // Decode RS1 | IMM7. - if (isImm) - MI.addOperand(MCOperand::createImm(imm7)); - else { - status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); - if (status != MCDisassembler::Success) - return status; - } - - // Decode CC - MI.addOperand(MCOperand::createImm(cc)); - - return MCDisassembler::Success; -} diff --git a/llvm/lib/Target/Sparc/SparcInstr64Bit.td b/llvm/lib/Target/Sparc/SparcInstr64Bit.td index 3b7e126..dc5400e 100644 --- a/llvm/lib/Target/Sparc/SparcInstr64Bit.td +++ b/llvm/lib/Target/Sparc/SparcInstr64Bit.td @@ -239,8 +239,7 @@ def UDIVXri : F3_2<2, 0b001101, let Predicates = [Is64Bit] in { // 64-bit loads. -let DecoderMethod = "DecodeLoadInt" in - defm LDX : Load<"ldx", 0b001011, load, I64Regs, i64>; +defm LDX : Load<"ldx", 0b001011, load, I64Regs, i64>; let mayLoad = 1, isAsmParserOnly = 1 in { def TLS_LDXrr : F3_1<3, 0b001011, @@ -283,12 +282,10 @@ def : Pat<(i64 (extloadi32 ADDRrr:$addr)), (LDrr ADDRrr:$addr)>; def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri ADDRri:$addr)>; // Sign-extending load of i32 into i64 is a new SPARC v9 instruction. -let DecoderMethod = "DecodeLoadInt" in - defm LDSW : Load<"ldsw", 0b001000, sextloadi32, I64Regs, i64>; +defm LDSW : Load<"ldsw", 0b001000, sextloadi32, I64Regs, i64>; // 64-bit stores. -let DecoderMethod = "DecodeStoreInt" in - defm STX : Store<"stx", 0b001110, store, I64Regs, i64>; +defm STX : Store<"stx", 0b001110, store, I64Regs, i64>; // Truncating stores from i64 are identical to the i32 stores. def : Pat<(truncstorei8 i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>; diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td index c8c5ba0..561de9b 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -138,12 +138,12 @@ def SparcMEMriAsmOperand : AsmOperandClass { def MEMrr : Operand { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops ptr_rc:$rs1, ptr_rc:$rs2); + let MIOperandInfo = (ops ptr_rc, ptr_rc); let ParserMatchClass = SparcMEMrrAsmOperand; } def MEMri : Operand { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops ptr_rc:$rs1, i32imm:$simm13); + let MIOperandInfo = (ops ptr_rc, i32imm); let ParserMatchClass = SparcMEMriAsmOperand; } @@ -419,7 +419,6 @@ multiclass LoadA Op3Val, bits<6> LoadAOp3Val, // The LDSTUB instruction is supported for asm only. // It is unlikely that general-purpose code could make use of it. // CAS is preferred for sparc v9. -let DecoderMethod = "DecodeFIXMEInstruction" in { def LDSTUBrr : F3_1<3, 0b001101, (outs IntRegs:$rd), (ins (MEMrr $rs1, $rs2):$addr), "ldstub [$addr], $rd", []>; def LDSTUBri : F3_2<3, 0b001101, (outs IntRegs:$rd), (ins (MEMri $rs1, $simm13):$addr), @@ -427,7 +426,6 @@ def LDSTUBri : F3_2<3, 0b001101, (outs IntRegs:$rd), (ins (MEMri $rs1, $simm13): def LDSTUBArr : F3_1_asi<3, 0b011101, (outs IntRegs:$rd), (ins (MEMrr $rs1, $rs2):$addr, i8imm:$asi), "ldstuba [$addr] $asi, $rd", []>; -} // Store multiclass - Define both Reg+Reg/Reg+Imm patterns in one shot. multiclass Store Op3Val, SDPatternOperator OpNode, @@ -563,38 +561,28 @@ let usesCustomInserter = 1, Uses = [FCC0] in { } // Section B.1 - Load Integer Instructions, p. 90 -let DecoderMethod = "DecodeLoadInt" in { - defm LDSB : LoadA<"ldsb", 0b001001, 0b011001, sextloadi8, IntRegs, i32>; - defm LDSH : LoadA<"ldsh", 0b001010, 0b011010, sextloadi16, IntRegs, i32>; - defm LDUB : LoadA<"ldub", 0b000001, 0b010001, zextloadi8, IntRegs, i32>; - defm LDUH : LoadA<"lduh", 0b000010, 0b010010, zextloadi16, IntRegs, i32>; - defm LD : LoadA<"ld", 0b000000, 0b010000, load, IntRegs, i32>; -} - -let DecoderMethod = "DecodeLoadIntPair" in - defm LDD : LoadA<"ldd", 0b000011, 0b010011, load, IntPair, v2i32, IIC_ldd>; +defm LDSB : LoadA<"ldsb", 0b001001, 0b011001, sextloadi8, IntRegs, i32>; +defm LDSH : LoadA<"ldsh", 0b001010, 0b011010, sextloadi16, IntRegs, i32>; +defm LDUB : LoadA<"ldub", 0b000001, 0b010001, zextloadi8, IntRegs, i32>; +defm LDUH : LoadA<"lduh", 0b000010, 0b010010, zextloadi16, IntRegs, i32>; +defm LD : LoadA<"ld", 0b000000, 0b010000, load, IntRegs, i32>; +defm LDD : LoadA<"ldd", 0b000011, 0b010011, load, IntPair, v2i32, IIC_ldd>; // Section B.2 - Load Floating-point Instructions, p. 92 -let DecoderMethod = "DecodeLoadFP" in { - defm LDF : Load<"ld", 0b100000, load, FPRegs, f32, IIC_iu_or_fpu_instr>; - def LDFArr : LoadASI<"ld", 0b110000, FPRegs>, - Requires<[HasV9]>; -} -let DecoderMethod = "DecodeLoadDFP" in { - defm LDDF : Load<"ldd", 0b100011, load, DFPRegs, f64, IIC_ldd>; - def LDDFArr : LoadASI<"ldd", 0b110011, DFPRegs>, - Requires<[HasV9]>; -} -let DecoderMethod = "DecodeLoadQFP" in - defm LDQF : LoadA<"ldq", 0b100010, 0b110010, load, QFPRegs, f128>, - Requires<[HasV9, HasHardQuad]>; - -let DecoderMethod = "DecodeLoadCP" in - defm LDC : Load<"ld", 0b110000, load, CoprocRegs, i32>; -let DecoderMethod = "DecodeLoadCPPair" in - defm LDDC : Load<"ldd", 0b110011, load, CoprocPair, v2i32, IIC_ldd>; - -let DecoderMethod = "DecodeLoadCP", Defs = [CPSR] in { +defm LDF : Load<"ld", 0b100000, load, FPRegs, f32, IIC_iu_or_fpu_instr>; +def LDFArr : LoadASI<"ld", 0b110000, FPRegs>, + Requires<[HasV9]>; + +defm LDDF : Load<"ldd", 0b100011, load, DFPRegs, f64, IIC_ldd>; +def LDDFArr : LoadASI<"ldd", 0b110011, DFPRegs>, + Requires<[HasV9]>; +defm LDQF : LoadA<"ldq", 0b100010, 0b110010, load, QFPRegs, f128>, + Requires<[HasV9, HasHardQuad]>; + +defm LDC : Load<"ld", 0b110000, load, CoprocRegs, i32>; +defm LDDC : Load<"ldd", 0b110011, load, CoprocPair, v2i32, IIC_ldd>; + +let Defs = [CPSR] in { let rd = 0 in { def LDCSRrr : F3_1<3, 0b110001, (outs), (ins (MEMrr $rs1, $rs2):$addr), "ld [$addr], %csr", []>; @@ -603,21 +591,20 @@ let DecoderMethod = "DecodeLoadCP", Defs = [CPSR] in { } } -let DecoderMethod = "DecodeLoadFP" in - let Defs = [FSR] in { - let rd = 0 in { - def LDFSRrr : F3_1<3, 0b100001, (outs), (ins (MEMrr $rs1, $rs2):$addr), - "ld [$addr], %fsr", [], IIC_iu_or_fpu_instr>; - def LDFSRri : F3_2<3, 0b100001, (outs), (ins (MEMri $rs1, $simm13):$addr), - "ld [$addr], %fsr", [], IIC_iu_or_fpu_instr>; - } - let rd = 1 in { - def LDXFSRrr : F3_1<3, 0b100001, (outs), (ins (MEMrr $rs1, $rs2):$addr), - "ldx [$addr], %fsr", []>, Requires<[HasV9]>; - def LDXFSRri : F3_2<3, 0b100001, (outs), (ins (MEMri $rs1, $simm13):$addr), - "ldx [$addr], %fsr", []>, Requires<[HasV9]>; - } +let Defs = [FSR] in { + let rd = 0 in { + def LDFSRrr : F3_1<3, 0b100001, (outs), (ins (MEMrr $rs1, $rs2):$addr), + "ld [$addr], %fsr", [], IIC_iu_or_fpu_instr>; + def LDFSRri : F3_2<3, 0b100001, (outs), (ins (MEMri $rs1, $simm13):$addr), + "ld [$addr], %fsr", [], IIC_iu_or_fpu_instr>; + } + let rd = 1 in { + def LDXFSRrr : F3_1<3, 0b100001, (outs), (ins (MEMrr $rs1, $rs2):$addr), + "ldx [$addr], %fsr", []>, Requires<[HasV9]>; + def LDXFSRri : F3_2<3, 0b100001, (outs), (ins (MEMri $rs1, $simm13):$addr), + "ldx [$addr], %fsr", []>, Requires<[HasV9]>; } +} let mayLoad = 1, isAsmParserOnly = 1 in { def GDOP_LDrr : F3_1<3, 0b000000, @@ -629,37 +616,25 @@ let mayLoad = 1, isAsmParserOnly = 1 in { } // Section B.4 - Store Integer Instructions, p. 95 -let DecoderMethod = "DecodeStoreInt" in { - defm STB : StoreA<"stb", 0b000101, 0b010101, truncstorei8, IntRegs, i32>; - defm STH : StoreA<"sth", 0b000110, 0b010110, truncstorei16, IntRegs, i32>; - defm ST : StoreA<"st", 0b000100, 0b010100, store, IntRegs, i32>; -} - -let DecoderMethod = "DecodeStoreIntPair" in - defm STD : StoreA<"std", 0b000111, 0b010111, store, IntPair, v2i32>; +defm STB : StoreA<"stb", 0b000101, 0b010101, truncstorei8, IntRegs, i32>; +defm STH : StoreA<"sth", 0b000110, 0b010110, truncstorei16, IntRegs, i32>; +defm ST : StoreA<"st", 0b000100, 0b010100, store, IntRegs, i32>; +defm STD : StoreA<"std", 0b000111, 0b010111, store, IntPair, v2i32>; // Section B.5 - Store Floating-point Instructions, p. 97 -let DecoderMethod = "DecodeStoreFP" in { - defm STF : Store<"st", 0b100100, store, FPRegs, f32>; - def STFArr : StoreASI<"st", 0b110100, FPRegs>, - Requires<[HasV9]>; -} -let DecoderMethod = "DecodeStoreDFP" in { - defm STDF : Store<"std", 0b100111, store, DFPRegs, f64, IIC_std>; - def STDFArr : StoreASI<"std", 0b110111, DFPRegs>, - Requires<[HasV9]>; -} -let DecoderMethod = "DecodeStoreQFP" in - defm STQF : StoreA<"stq", 0b100110, 0b110110, store, QFPRegs, f128>, - Requires<[HasV9, HasHardQuad]>; - -let DecoderMethod = "DecodeStoreCP" in - defm STC : Store<"st", 0b110100, store, CoprocRegs, i32>; - -let DecoderMethod = "DecodeStoreCPPair" in - defm STDC : Store<"std", 0b110111, store, CoprocPair, v2i32, IIC_std>; - -let DecoderMethod = "DecodeStoreCP", rd = 0 in { +defm STF : Store<"st", 0b100100, store, FPRegs, f32>; +def STFArr : StoreASI<"st", 0b110100, FPRegs>, + Requires<[HasV9]>; +defm STDF : Store<"std", 0b100111, store, DFPRegs, f64, IIC_std>; +def STDFArr : StoreASI<"std", 0b110111, DFPRegs>, + Requires<[HasV9]>; +defm STQF : StoreA<"stq", 0b100110, 0b110110, store, QFPRegs, f128>, + Requires<[HasV9, HasHardQuad]>; + +defm STC : Store<"st", 0b110100, store, CoprocRegs, i32>; +defm STDC : Store<"std", 0b110111, store, CoprocPair, v2i32, IIC_std>; + +let rd = 0 in { let Defs = [CPSR] in { def STCSRrr : F3_1<3, 0b110101, (outs (MEMrr $rs1, $rs2):$addr), (ins), "st %csr, [$addr]", [], IIC_st>; @@ -674,32 +649,30 @@ let DecoderMethod = "DecodeStoreCP", rd = 0 in { } } -let DecoderMethod = "DecodeStoreFP" in { - let rd = 0 in { - let Defs = [FSR] in { - def STFSRrr : F3_1<3, 0b100101, (outs (MEMrr $rs1, $rs2):$addr), (ins), - "st %fsr, [$addr]", [], IIC_st>; - def STFSRri : F3_2<3, 0b100101, (outs (MEMri $rs1, $simm13):$addr), (ins), - "st %fsr, [$addr]", [], IIC_st>; - } - let Defs = [FQ] in { - def STDFQrr : F3_1<3, 0b100110, (outs (MEMrr $rs1, $rs2):$addr), (ins), - "std %fq, [$addr]", [], IIC_std>; - def STDFQri : F3_2<3, 0b100110, (outs (MEMri $rs1, $simm13):$addr), (ins), - "std %fq, [$addr]", [], IIC_std>; - } +let rd = 0 in { + let Defs = [FSR] in { + def STFSRrr : F3_1<3, 0b100101, (outs (MEMrr $rs1, $rs2):$addr), (ins), + "st %fsr, [$addr]", [], IIC_st>; + def STFSRri : F3_2<3, 0b100101, (outs (MEMri $rs1, $simm13):$addr), (ins), + "st %fsr, [$addr]", [], IIC_st>; } - let rd = 1, Defs = [FSR] in { - def STXFSRrr : F3_1<3, 0b100101, (outs (MEMrr $rs1, $rs2):$addr), (ins), - "stx %fsr, [$addr]", []>, Requires<[HasV9]>; - def STXFSRri : F3_2<3, 0b100101, (outs (MEMri $rs1, $simm13):$addr), (ins), - "stx %fsr, [$addr]", []>, Requires<[HasV9]>; + let Defs = [FQ] in { + def STDFQrr : F3_1<3, 0b100110, (outs (MEMrr $rs1, $rs2):$addr), (ins), + "std %fq, [$addr]", [], IIC_std>; + def STDFQri : F3_2<3, 0b100110, (outs (MEMri $rs1, $simm13):$addr), (ins), + "std %fq, [$addr]", [], IIC_std>; } } +let rd = 1, Defs = [FSR] in { + def STXFSRrr : F3_1<3, 0b100101, (outs (MEMrr $rs1, $rs2):$addr), (ins), + "stx %fsr, [$addr]", []>, Requires<[HasV9]>; + def STXFSRri : F3_2<3, 0b100101, (outs (MEMri $rs1, $simm13):$addr), (ins), + "stx %fsr, [$addr]", []>, Requires<[HasV9]>; +} // Section B.8 - SWAP Register with Memory Instruction // (Atomic swap) -let Constraints = "$val = $rd", DecoderMethod = "DecodeSWAP" in { +let Constraints = "$val = $rd" in { def SWAPrr : F3_1<3, 0b001111, (outs IntRegs:$rd), (ins (MEMrr $rs1, $rs2):$addr, IntRegs:$val), "swap [$addr], $rd", @@ -1032,8 +1005,7 @@ let Uses = [O6], // Section B.25 - Jump and Link Instruction // JMPL Instruction. -let isTerminator = 1, hasDelaySlot = 1, isBarrier = 1, - DecoderMethod = "DecodeJMPL" in { +let isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in { def JMPLrr: F3_1<2, 0b111000, (outs IntRegs:$rd), (ins (MEMrr $rs1, $rs2):$addr), "jmpl $addr, $rd", @@ -1067,7 +1039,7 @@ let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1, // Section B.26 - Return from Trap Instruction let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, - isBarrier = 1, rd = 0, DecoderMethod = "DecodeReturn" in { + isBarrier = 1, rd = 0 in { def RETTrr : F3_1<2, 0b111001, (outs), (ins (MEMrr $rs1, $rs2):$addr), "rett $addr", @@ -1083,7 +1055,7 @@ let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, // Section B.27 - Trap on Integer Condition Codes Instruction // conditional branch class: -let DecoderNamespace = "SparcV8", DecoderMethod = "DecodeTRAP", hasSideEffects = 1, Uses = [ICC], cc = 0b00 in +let DecoderNamespace = "SparcV8", hasSideEffects = 1, Uses = [ICC], cc = 0b00 in { def TRAPrr : TRAPSPrr<0b111010, (outs), (ins IntRegs:$rs1, IntRegs:$rs2, CCOp:$cond), @@ -1106,7 +1078,7 @@ multiclass TRAP { []>; } -let DecoderNamespace = "SparcV9", DecoderMethod = "DecodeTRAP", Predicates = [HasV9], hasSideEffects = 1, Uses = [ICC], cc = 0b00 in +let DecoderNamespace = "SparcV9", Predicates = [HasV9], hasSideEffects = 1, Uses = [ICC], cc = 0b00 in defm TICC : TRAP<"%icc">; @@ -1197,7 +1169,7 @@ let rd = 0 in "unimp $imm22", []>; // Section B.32 - Flush Instruction Memory -let DecoderMethod = "DecodeFIXMEInstruction", rd = 0 in { +let rd = 0 in { def FLUSHrr : F3_1<2, 0b111011, (outs), (ins (MEMrr $rs1, $rs2):$addr), "flush $addr", []>; def FLUSHri : F3_2<2, 0b111011, (outs), (ins (MEMri $rs1, $simm13):$addr), @@ -1761,7 +1733,7 @@ let hasSideEffects = 1 in { } // Section A.42 - Prefetch Data -let DecoderMethod = "DecodeFIXMEInstruction", Predicates = [HasV9] in { +let Predicates = [HasV9] in { def PREFETCHr : F3_1<3, 0b101101, (outs), (ins (MEMrr $rs1, $rs2):$addr, shift_imm5:$rd), "prefetch [$addr], $rd", []>; diff --git a/llvm/test/MC/Disassembler/Sparc/sparc-coproc.txt b/llvm/test/MC/Disassembler/Sparc/sparc-coproc.txt new file mode 100644 index 0000000..e3b490c --- /dev/null +++ b/llvm/test/MC/Disassembler/Sparc/sparc-coproc.txt @@ -0,0 +1,85 @@ +# RUN: llvm-mc --disassemble %s -triple=sparc-unknown-linux | FileCheck %s + +# CHECK: ld [%i0+%l6], %c10 +0xd5 0x86 0x00 0x16 + +# CHECK: ld [%i0+32], %c10 +0xd5 0x86 0x20 0x20 + +# CHECK: ld [%g1], %c10 +0xd5 0x80 0x60 0x00 + +# CHECK: ld [%g1], %c10 +0xd5 0x80 0x40 0x00 + +# CHECK: st %c10, [%i0+%l6] +0xd5 0xa6 0x00 0x16 + +# CHECK: st %c10, [%i0+32] +0xd5 0xa6 0x20 0x20 + +# CHECK: st %c10, [%g1] +0xd5 0xa0 0x60 0x00 + +# CHECK: st %c10, [%g1] +0xd5 0xa0 0x40 0x00 + +# CHECK: ldd [%i0+%l6], %c10 +0xd5 0x9e 0x00 0x16 + +# CHECK: ldd [%i0+32], %c10 +0xd5 0x9e 0x20 0x20 + +# CHECK: ldd [%g1], %c10 +0xd5 0x98 0x60 0x00 + +# CHECK: ldd [%g1], %c10 +0xd5 0x98 0x40 0x00 + +# CHECK: std %c10, [%i0+%l6] +0xd5 0xbe 0x00 0x16 + +# CHECK: std %c10, [%i0+32] +0xd5 0xbe 0x20 0x20 + +# CHECK: std %c10, [%g1] +0xd5 0xb8 0x60 0x00 + +# CHECK: std %c10, [%g1] +0xd5 0xb8 0x40 0x00 + +# CHECK: ld [%i0+%l6], %csr +0xc1 0x8e 0x00 0x16 + +# CHECK: ld [%i0+32], %csr +0xc1 0x8e 0x20 0x20 + +# CHECK: ld [%g1], %csr +0xc1 0x88 0x60 0x00 + +# CHECK: ld [%g1], %csr +0xc1 0x88 0x40 0x00 + +# CHECK: st %csr, [%i0+%l6] +0xc1 0xae 0x00 0x16 + +# CHECK: st %csr, [%i0+32] +0xc1 0xae 0x20 0x20 + +# CHECK: st %csr, [%g1] +0xc1 0xa8 0x60 0x00 + +# CHECK: st %csr, [%g1] +0xc1 0xa8 0x40 0x00 + +# CHECK: std %cq, [%i0+%l6] +0xc1 0xb6 0x00 0x16 + +# CHECK: std %cq, [%i0+32] +0xc1 0xb6 0x20 0x20 + +# CHECK: std %cq, [%g1] +0xc1 0xb0 0x60 0x00 + +# CHECK: std %cq, [%g1] +0xc1 0xb0 0x40 0x00 diff --git a/llvm/test/MC/Disassembler/Sparc/sparc-mem.txt b/llvm/test/MC/Disassembler/Sparc/sparc-mem.txt index 04a0365..87474fa 100644 --- a/llvm/test/MC/Disassembler/Sparc/sparc-mem.txt +++ b/llvm/test/MC/Disassembler/Sparc/sparc-mem.txt @@ -12,6 +12,9 @@ # CHECK: ldsb [%g1], %o4 0xd8 0x48 0x40 0x00 +# CHECK: ldsba [%i0+%l6] 131, %o2 +0xd4 0xce 0x10 0x76 + # CHECK: ldsh [%i0+%l6], %o2 0xd4 0x56 0x00 0x16 @@ -24,6 +27,9 @@ # CHECK: ldsh [%g1], %o4 0xd8 0x50 0x40 0x00 +# CHECK: ldsha [%i0+%l6] 131, %o2 +0xd4 0xd6 0x10 0x76 + # CHECK: ldub [%i0+%l6], %o2 0xd4 0x0e 0x00 0x16 @@ -36,6 +42,9 @@ # CHECK: ldub [%g1], %o2 0xd4 0x08 0x40 0x00 +# CHECK: lduba [%i0+%l6] 131, %o2 +0xd4 0x8e 0x10 0x76 + # CHECK: lduh [%i0+%l6], %o2 0xd4 0x16 0x00 0x16 @@ -48,6 +57,9 @@ # CHECK: lduh [%g1], %o2 0xd4 0x10 0x40 0x00 +# CHECK: lduha [%i0+%l6] 131, %o2 +0xd4 0x96 0x10 0x76 + # CHECK: ld [%i0+%l6], %o2 0xd4 0x06 0x00 0x16 @@ -60,6 +72,9 @@ # CHECK: ld [%g1], %o2 0xd4 0x00 0x40 0x00 +# CHECK: lda [%i0+%l6] 131, %o2 +0xd4 0x86 0x10 0x76 + # CHECK: ld [%i0+%l6], %f2 0xc5 0x06 0x00 0x16 @@ -72,6 +87,9 @@ # CHECK: ld [%g1], %f2 0xc5 0x00 0x40 0x00 +# CHECK: lda [%i0+%l6] 131, %f2 +0xc5 0x86 0x10 0x76 + # CHECK: ldd [%i0+%l6], %f2 0xc5 0x1e 0x00 0x16 @@ -84,6 +102,9 @@ # CHECK: ldd [%g1], %f2 0xc5 0x18 0x40 0x00 +# CHECK: ldda [%i0+%l6] 131, %f2 +0xc5 0x9e 0x10 0x76 + # CHECK: ldq [%i0+%l6], %f4 0xc9 0x16 0x00 0x16 @@ -132,6 +153,9 @@ # CHECK: stb %o2, [%g1] 0xd4 0x28 0x40 0x00 +# CHECK: stba %o2, [%i0+%l6] 131 +0xd4 0xae 0x10 0x76 + # CHECK: sth %o2, [%i0+%l6] 0xd4 0x36 0x00 0x16 @@ -144,6 +168,9 @@ # CHECK: sth %o2, [%g1] 0xd4 0x30 0x40 0x00 +# CHECK: stha %o2, [%i0+%l6] 131 +0xd4 0xb6 0x10 0x76 + # CHECK: st %o2, [%i0+%l6] 0xd4 0x26 0x00 0x16 @@ -156,6 +183,9 @@ # CHECK: st %o2, [%g1] 0xd4 0x20 0x40 0x00 +# CHECK: sta %o2, [%i0+%l6] 131 +0xd4 0xa6 0x10 0x76 + # CHECK: st %f2, [%i0+%l6] 0xc5 0x26 0x00 0x16 @@ -168,6 +198,9 @@ # CHECK: st %f2, [%g1] 0xc5 0x20 0x40 0x00 +# CHECK: sta %f2, [%i0+%l6] 131 +0xc5 0xa6 0x10 0x76 + # CHECK: std %f2, [%i0+%l6] 0xc5 0x3e 0x00 0x16 @@ -180,6 +213,9 @@ # CHECK: std %f2, [%g1] 0xc5 0x38 0x40 0x00 +# CHECK: stda %f2, [%i0+%l6] 131 +0xc5 0xbe 0x10 0x76 + # CHECK: stq %f4, [%i0+%l6] 0xc9 0x36 0x00 0x16 @@ -245,3 +281,84 @@ # CHECK: std %o2, [%g1] 0xd4 0x38 0x40 0x00 + +# CHECK: stda %o2, [%i0+%l6] 131 +0xd4 0xbe 0x10 0x76 + +# CHECK: ldstub [%i0+%l6], %o2 +0xd4 0x6e 0x00 0x16 + +# CHECK: ldstub [%i0+32], %o2 +0xd4 0x6e 0x20 0x20 + +# CHECK: ldstub [%g1], %o2 +0xd4 0x68 0x60 0x00 + +# CHECK: ldstub [%g1], %o2 +0xd4 0x68 0x40 0x00 + +# CHECK: ldstuba [%i0+%l6] 131, %o2 +0xd4 0xee 0x10 0x76 + +# CHECK: ldstuba [%g1] 131, %o2 +0xd4 0xe8 0x50 0x60 + +# CHECK: flush %g1+%g2 +0x81 0xd8 0x40 0x02 + +# CHECK: flush %g1+8 +0x81 0xd8 0x60 0x08 + +# CHECK: flush %g1 +0x81 0xd8 0x40 0x00 + +# CHECK: flush %g1 +0x81 0xd8 0x60 0x00 + +# CHECK: ld [%i0+%l6], %fsr +0xc1 0x0e 0x00 0x16 + +# CHECK: ld [%i0+32], %fsr +0xc1 0x0e 0x20 0x20 + +# CHECK: ld [%g1], %fsr +0xc1 0x08 0x60 0x00 + +# CHECK: ld [%g1], %fsr +0xc1 0x08 0x40 0x00 + +# CHECK: st %fsr, [%i0+%l6] +0xc1 0x2e 0x00 0x16 + +# CHECK: st %fsr, [%i0+32] +0xc1 0x2e 0x20 0x20 + +# CHECK: st %fsr, [%g1] +0xc1 0x28 0x60 0x00 + +# CHECK: st %fsr, [%g1] +0xc1 0x28 0x40 0x00 + +# CHECK: ldx [%i0+%l6], %fsr +0xc3 0x0e 0x00 0x16 + +# CHECK: ldx [%i0+32], %fsr +0xc3 0x0e 0x20 0x20 + +# CHECK: ldx [%g1], %fsr +0xc3 0x08 0x60 0x00 + +# CHECK: ldx [%g1], %fsr +0xc3 0x08 0x40 0x00 + +# CHECK: stx %fsr, [%i0+%l6] +0xc3 0x2e 0x00 0x16 + +# CHECK: stx %fsr, [%i0+32] +0xc3 0x2e 0x20 0x20 + +# CHECK: stx %fsr, [%g1] +0xc3 0x28 0x60 0x00 + +# CHECK: stx %fsr, [%g1] +0xc3 0x28 0x40 0x00 diff --git a/llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt b/llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt index b34816d..1d5abab 100644 --- a/llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt +++ b/llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt @@ -36,11 +36,5 @@ # CHECK: st %fsr, [%i5] 0xc1 0x2f 0x40 0x00 -# CHECK: st %csr, [%i5] -0xc1 0xaf 0x40 0x00 - -# CHECK: std %cq, [%o3+-93] -0xc1 0xb2 0xff 0xa3 - # CHECK: std %fq, [%i5+%l1] 0xc1 0x37 0x40 0x11 diff --git a/llvm/test/MC/Disassembler/Sparc/sparc-v9.txt b/llvm/test/MC/Disassembler/Sparc/sparc-v9.txt index 8f68513..6545ce9 100644 --- a/llvm/test/MC/Disassembler/Sparc/sparc-v9.txt +++ b/llvm/test/MC/Disassembler/Sparc/sparc-v9.txt @@ -131,3 +131,9 @@ # CHECK: membar #LoadLoad | #StoreLoad | #LoadStore | #StoreStore | #Lookaside | #MemIssue | #Sync 0x81 0x43 0xe0 0x7f + +# CHECK: prefetch [%i1+3968], 1 +0xc3,0x6e,0x6f,0x80 + +# CHECK: prefetch [%i1+%i2], 1 +0xc3,0x6e,0x40,0x1a diff --git a/llvm/test/MC/Disassembler/Sparc/sparc.txt b/llvm/test/MC/Disassembler/Sparc/sparc.txt index 9c0b2a1..da1ac06 100644 --- a/llvm/test/MC/Disassembler/Sparc/sparc.txt +++ b/llvm/test/MC/Disassembler/Sparc/sparc.txt @@ -243,6 +243,9 @@ # CHECK: rett %i7+8 0x81 0xcf 0xe0 0x08 +# CHECK: rett %i7+%i0 +0x81 0xcf 0xc0 0x18 + # CHECK: stbar 0x81 0x43 0xc0 0x00 -- 2.7.4