1263320SdimPull in r198591 from upstream llvm trunk (by Venkatraman Govindaraju): 2263320Sdim 3263320Sdim [Sparc] Add initial implementation of disassembler for sparc 4263320Sdim 5269012SemasteIntroduced here: http://svnweb.freebsd.org/changeset/base/262261 6263320Sdim 7263320SdimIndex: lib/Target/Sparc/SparcInstrFormats.td 8263320Sdim=================================================================== 9263320Sdim--- lib/Target/Sparc/SparcInstrFormats.td 10263320Sdim+++ lib/Target/Sparc/SparcInstrFormats.td 11263320Sdim@@ -12,6 +12,7 @@ class InstSP<dag outs, dag ins, string asmstr, lis 12263320Sdim field bits<32> Inst; 13263320Sdim 14263320Sdim let Namespace = "SP"; 15263320Sdim+ let Size = 4; 16263320Sdim 17263320Sdim bits<2> op; 18263320Sdim let Inst{31-30} = op; // Top two bits are the 'op' field 19263320Sdim@@ -20,6 +21,9 @@ class InstSP<dag outs, dag ins, string asmstr, lis 20263320Sdim dag InOperandList = ins; 21263320Sdim let AsmString = asmstr; 22263320Sdim let Pattern = pattern; 23263320Sdim+ 24263320Sdim+ let DecoderNamespace = "Sparc"; 25263320Sdim+ field bits<32> SoftFail = 0; 26263320Sdim } 27263320Sdim 28263320Sdim //===----------------------------------------------------------------------===// 29263320Sdim@@ -58,6 +62,27 @@ class F2_2<bits<3> op2Val, dag outs, dag ins, stri 30263320Sdim let Inst{28-25} = cond; 31263320Sdim } 32263320Sdim 33263320Sdim+class F2_3<bits<3> op2Val, bits<2> ccVal, dag outs, dag ins, string asmstr, 34263320Sdim+ list<dag> pattern> 35263320Sdim+ : InstSP<outs, ins, asmstr, pattern> { 36263320Sdim+ bit annul; 37263320Sdim+ bits<4> cond; 38263320Sdim+ bit pred; 39263320Sdim+ bits<19> imm19; 40263320Sdim+ 41263320Sdim+ let op = 0; // op = 0 42263320Sdim+ 43263320Sdim+ bit annul = 0; // currently unused 44263320Sdim+ let pred = 1; // default is predict taken 45263320Sdim+ 46263320Sdim+ let Inst{29} = annul; 47263320Sdim+ let Inst{28-25} = cond; 48263320Sdim+ let Inst{24-22} = op2Val; 49263320Sdim+ let Inst{21-20} = ccVal; 50263320Sdim+ let Inst{19} = pred; 51263320Sdim+ let Inst{18-0} = imm19; 52263320Sdim+} 53263320Sdim+ 54263320Sdim //===----------------------------------------------------------------------===// 55263320Sdim // Format #3 instruction classes in the Sparc 56263320Sdim //===----------------------------------------------------------------------===// 57263320SdimIndex: lib/Target/Sparc/LLVMBuild.txt 58263320Sdim=================================================================== 59263320Sdim--- lib/Target/Sparc/LLVMBuild.txt 60263320Sdim+++ lib/Target/Sparc/LLVMBuild.txt 61263320Sdim@@ -16,13 +16,15 @@ 62263320Sdim ;===------------------------------------------------------------------------===; 63263320Sdim 64263320Sdim [common] 65263320Sdim-subdirectories = AsmParser InstPrinter MCTargetDesc TargetInfo 66263320Sdim+subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo 67263320Sdim 68263320Sdim [component_0] 69263320Sdim type = TargetGroup 70263320Sdim name = Sparc 71263320Sdim parent = Target 72263320Sdim+has_asmparser = 1 73263320Sdim has_asmprinter = 1 74263320Sdim+has_disassembler = 1 75263320Sdim has_jit = 1 76263320Sdim 77263320Sdim [component_1] 78263320SdimIndex: lib/Target/Sparc/SparcInstrInfo.td 79263320Sdim=================================================================== 80263320Sdim--- lib/Target/Sparc/SparcInstrInfo.td 81263320Sdim+++ lib/Target/Sparc/SparcInstrInfo.td 82263320Sdim@@ -230,13 +230,13 @@ def FCC_O : FCC_VAL<29>; // Ordered 83263320Sdim multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode, 84263320Sdim RegisterClass RC, ValueType Ty, Operand immOp> { 85263320Sdim def rr : F3_1<2, Op3Val, 86263320Sdim- (outs RC:$dst), (ins RC:$b, RC:$c), 87263320Sdim- !strconcat(OpcStr, " $b, $c, $dst"), 88263320Sdim- [(set Ty:$dst, (OpNode Ty:$b, Ty:$c))]>; 89263320Sdim+ (outs RC:$rd), (ins RC:$rs1, RC:$rs2), 90263320Sdim+ !strconcat(OpcStr, " $rs1, $rs2, $rd"), 91263320Sdim+ [(set Ty:$rd, (OpNode Ty:$rs1, Ty:$rs2))]>; 92263320Sdim def ri : F3_2<2, Op3Val, 93263320Sdim- (outs RC:$dst), (ins RC:$b, immOp:$c), 94263320Sdim- !strconcat(OpcStr, " $b, $c, $dst"), 95263320Sdim- [(set Ty:$dst, (OpNode Ty:$b, (Ty simm13:$c)))]>; 96263320Sdim+ (outs RC:$rd), (ins RC:$rs1, immOp:$simm13), 97263320Sdim+ !strconcat(OpcStr, " $rs1, $simm13, $rd"), 98263320Sdim+ [(set Ty:$rd, (OpNode Ty:$rs1, (Ty simm13:$simm13)))]>; 99263320Sdim } 100263320Sdim 101263320Sdim /// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no 102263320Sdim@@ -243,11 +243,11 @@ multiclass F3_12<string OpcStr, bits<6> Op3Val, SD 103263320Sdim /// pattern. 104263320Sdim multiclass F3_12np<string OpcStr, bits<6> Op3Val> { 105263320Sdim def rr : F3_1<2, Op3Val, 106263320Sdim- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 107263320Sdim- !strconcat(OpcStr, " $b, $c, $dst"), []>; 108263320Sdim+ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 109263320Sdim+ !strconcat(OpcStr, " $rs1, $rs2, $rd"), []>; 110263320Sdim def ri : F3_2<2, Op3Val, 111263320Sdim- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), 112263320Sdim- !strconcat(OpcStr, " $b, $c, $dst"), []>; 113263320Sdim+ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), 114263320Sdim+ !strconcat(OpcStr, " $rs1, $simm13, $rd"), []>; 115263320Sdim } 116263320Sdim 117263320Sdim //===----------------------------------------------------------------------===// 118263320Sdim@@ -488,31 +488,31 @@ let rd = 0, imm22 = 0 in 119263320Sdim defm AND : F3_12<"and", 0b000001, and, IntRegs, i32, i32imm>; 120263320Sdim 121263320Sdim def ANDNrr : F3_1<2, 0b000101, 122263320Sdim- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 123263320Sdim- "andn $b, $c, $dst", 124263320Sdim- [(set i32:$dst, (and i32:$b, (not i32:$c)))]>; 125263320Sdim+ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 126263320Sdim+ "andn $rs1, $rs2, $rd", 127263320Sdim+ [(set i32:$rd, (and i32:$rs1, (not i32:$rs2)))]>; 128263320Sdim def ANDNri : F3_2<2, 0b000101, 129263320Sdim- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), 130263320Sdim- "andn $b, $c, $dst", []>; 131263320Sdim+ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), 132263320Sdim+ "andn $rs1, $simm13, $rd", []>; 133263320Sdim 134263320Sdim defm OR : F3_12<"or", 0b000010, or, IntRegs, i32, i32imm>; 135263320Sdim 136263320Sdim def ORNrr : F3_1<2, 0b000110, 137263320Sdim- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 138263320Sdim- "orn $b, $c, $dst", 139263320Sdim- [(set i32:$dst, (or i32:$b, (not i32:$c)))]>; 140263320Sdim+ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 141263320Sdim+ "orn $rs1, $rs2, $rd", 142263320Sdim+ [(set i32:$rd, (or i32:$rs1, (not i32:$rs2)))]>; 143263320Sdim def ORNri : F3_2<2, 0b000110, 144263320Sdim- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), 145263320Sdim- "orn $b, $c, $dst", []>; 146263320Sdim+ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), 147263320Sdim+ "orn $rs1, $simm13, $rd", []>; 148263320Sdim defm XOR : F3_12<"xor", 0b000011, xor, IntRegs, i32, i32imm>; 149263320Sdim 150263320Sdim def XNORrr : F3_1<2, 0b000111, 151263320Sdim- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 152263320Sdim- "xnor $b, $c, $dst", 153263320Sdim- [(set i32:$dst, (not (xor i32:$b, i32:$c)))]>; 154263320Sdim+ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), 155263320Sdim+ "xnor $rs1, $rs2, $rd", 156263320Sdim+ [(set i32:$rd, (not (xor i32:$rs1, i32:$rs2)))]>; 157263320Sdim def XNORri : F3_2<2, 0b000111, 158263320Sdim- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), 159263320Sdim- "xnor $b, $c, $dst", []>; 160263320Sdim+ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), 161263320Sdim+ "xnor $rs1, $simm13, $rd", []>; 162263320Sdim 163263320Sdim // Section B.12 - Shift Instructions, p. 107 164263320Sdim defm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, i32imm>; 165263320Sdim@@ -545,21 +545,15 @@ let Defs = [ICC] in 166263320Sdim 167263320Sdim let Defs = [ICC], rd = 0 in { 168263320Sdim def CMPrr : F3_1<2, 0b010100, 169263320Sdim- (outs), (ins IntRegs:$b, IntRegs:$c), 170263320Sdim- "cmp $b, $c", 171263320Sdim- [(SPcmpicc i32:$b, i32:$c)]>; 172263320Sdim+ (outs), (ins IntRegs:$rs1, IntRegs:$rs2), 173263320Sdim+ "cmp $rs1, $rs2", 174263320Sdim+ [(SPcmpicc i32:$rs1, i32:$rs2)]>; 175263320Sdim def CMPri : F3_2<2, 0b010100, 176263320Sdim- (outs), (ins IntRegs:$b, i32imm:$c), 177263320Sdim- "cmp $b, $c", 178263320Sdim- [(SPcmpicc i32:$b, (i32 simm13:$c))]>; 179263320Sdim+ (outs), (ins IntRegs:$rs1, i32imm:$simm13), 180263320Sdim+ "cmp $rs1, $simm13", 181263320Sdim+ [(SPcmpicc i32:$rs1, (i32 simm13:$simm13))]>; 182263320Sdim } 183263320Sdim 184263320Sdim-let Uses = [ICC], Defs = [ICC] in 185263320Sdim- def SUBXCCrr: F3_1<2, 0b011100, 186263320Sdim- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 187263320Sdim- "subxcc $b, $c, $dst", []>; 188263320Sdim- 189263320Sdim- 190263320Sdim // Section B.18 - Multiply Instructions, p. 113 191263320Sdim let Defs = [Y] in { 192263320Sdim defm UMUL : F3_12np<"umul", 0b001010>; 193263320Sdim@@ -858,7 +852,7 @@ let Defs = [FCC] in { 194263320Sdim //===----------------------------------------------------------------------===// 195263320Sdim // Instructions for Thread Local Storage(TLS). 196263320Sdim //===----------------------------------------------------------------------===// 197263320Sdim- 198263320Sdim+let isCodeGenOnly = 1, isAsmParserOnly = 1 in { 199263320Sdim def TLS_ADDrr : F3_1<2, 0b000000, 200263320Sdim (outs IntRegs:$rd), 201263320Sdim (ins IntRegs:$rs1, IntRegs:$rs2, TLSSym:$sym), 202263320Sdim@@ -882,6 +876,7 @@ let Uses = [O6], isCall = 1, hasDelaySlot = 1 in 203263320Sdim let op = 1; 204263320Sdim let Inst{29-0} = disp; 205263320Sdim } 206263320Sdim+} 207263320Sdim 208263320Sdim //===----------------------------------------------------------------------===// 209263320Sdim // V9 Instructions 210263320SdimIndex: lib/Target/Sparc/CMakeLists.txt 211263320Sdim=================================================================== 212263320Sdim--- lib/Target/Sparc/CMakeLists.txt 213263320Sdim+++ lib/Target/Sparc/CMakeLists.txt 214263320Sdim@@ -3,6 +3,7 @@ set(LLVM_TARGET_DEFINITIONS Sparc.td) 215263320Sdim tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info) 216263320Sdim tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info) 217263320Sdim tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter) 218263320Sdim+tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler) 219263320Sdim tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter -mc-emitter) 220263320Sdim tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer) 221263320Sdim tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher) 222263320Sdim@@ -34,3 +35,4 @@ add_subdirectory(TargetInfo) 223263320Sdim add_subdirectory(MCTargetDesc) 224263320Sdim add_subdirectory(InstPrinter) 225263320Sdim add_subdirectory(AsmParser) 226263320Sdim+add_subdirectory(Disassembler) 227263320SdimIndex: lib/Target/Sparc/Disassembler/SparcDisassembler.cpp 228263320Sdim=================================================================== 229263320Sdim--- lib/Target/Sparc/Disassembler/SparcDisassembler.cpp 230263320Sdim+++ lib/Target/Sparc/Disassembler/SparcDisassembler.cpp 231263320Sdim@@ -0,0 +1,228 @@ 232263320Sdim+//===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===// 233263320Sdim+// 234263320Sdim+// The LLVM Compiler Infrastructure 235263320Sdim+// 236263320Sdim+// This file is distributed under the University of Illinois Open Source 237263320Sdim+// License. See LICENSE.TXT for details. 238263320Sdim+// 239263320Sdim+//===----------------------------------------------------------------------===// 240263320Sdim+// 241263320Sdim+// This file is part of the Sparc Disassembler. 242263320Sdim+// 243263320Sdim+//===----------------------------------------------------------------------===// 244263320Sdim+ 245263320Sdim+#define DEBUG_TYPE "sparc-disassembler" 246263320Sdim+ 247263320Sdim+#include "Sparc.h" 248263320Sdim+#include "SparcRegisterInfo.h" 249263320Sdim+#include "SparcSubtarget.h" 250263320Sdim+#include "llvm/MC/MCDisassembler.h" 251263320Sdim+#include "llvm/MC/MCFixedLenDisassembler.h" 252263320Sdim+#include "llvm/Support/MemoryObject.h" 253263320Sdim+#include "llvm/Support/TargetRegistry.h" 254263320Sdim+ 255263320Sdim+using namespace llvm; 256263320Sdim+ 257263320Sdim+typedef MCDisassembler::DecodeStatus DecodeStatus; 258263320Sdim+ 259263320Sdim+namespace { 260263320Sdim+ 261263320Sdim+/// SparcDisassembler - a disassembler class for Sparc. 262263320Sdim+class SparcDisassembler : public MCDisassembler { 263263320Sdim+public: 264263320Sdim+ /// Constructor - Initializes the disassembler. 265263320Sdim+ /// 266263320Sdim+ SparcDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) : 267263320Sdim+ MCDisassembler(STI), RegInfo(Info) 268263320Sdim+ {} 269263320Sdim+ virtual ~SparcDisassembler() {} 270263320Sdim+ 271263320Sdim+ const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } 272263320Sdim+ 273263320Sdim+ /// getInstruction - See MCDisassembler. 274263320Sdim+ virtual DecodeStatus getInstruction(MCInst &instr, 275263320Sdim+ uint64_t &size, 276263320Sdim+ const MemoryObject ®ion, 277263320Sdim+ uint64_t address, 278263320Sdim+ raw_ostream &vStream, 279263320Sdim+ raw_ostream &cStream) const; 280263320Sdim+private: 281263320Sdim+ OwningPtr<const MCRegisterInfo> RegInfo; 282263320Sdim+}; 283263320Sdim+ 284263320Sdim+} 285263320Sdim+ 286263320Sdim+namespace llvm { 287263320Sdim+ extern Target TheSparcTarget, TheSparcV9Target; 288263320Sdim+} 289263320Sdim+ 290263320Sdim+static MCDisassembler *createSparcDisassembler( 291263320Sdim+ const Target &T, 292263320Sdim+ const MCSubtargetInfo &STI) { 293263320Sdim+ return new SparcDisassembler(STI, T.createMCRegInfo("")); 294263320Sdim+} 295263320Sdim+ 296263320Sdim+ 297263320Sdim+extern "C" void LLVMInitializeSparcDisassembler() { 298263320Sdim+ // Register the disassembler. 299263320Sdim+ TargetRegistry::RegisterMCDisassembler(TheSparcTarget, 300263320Sdim+ createSparcDisassembler); 301263320Sdim+ TargetRegistry::RegisterMCDisassembler(TheSparcV9Target, 302263320Sdim+ createSparcDisassembler); 303263320Sdim+} 304263320Sdim+ 305263320Sdim+ 306263320Sdim+ 307263320Sdim+static const unsigned IntRegDecoderTable[] = { 308263320Sdim+ SP::G0, SP::G1, SP::G2, SP::G3, 309263320Sdim+ SP::G4, SP::G5, SP::G6, SP::G7, 310263320Sdim+ SP::O0, SP::O1, SP::O2, SP::O3, 311263320Sdim+ SP::O4, SP::O5, SP::O6, SP::O7, 312263320Sdim+ SP::L0, SP::L1, SP::L2, SP::L3, 313263320Sdim+ SP::L4, SP::L5, SP::L6, SP::L7, 314263320Sdim+ SP::I0, SP::I1, SP::I2, SP::I3, 315263320Sdim+ SP::I4, SP::I5, SP::I6, SP::I7 }; 316263320Sdim+ 317263320Sdim+static const unsigned FPRegDecoderTable[] = { 318263320Sdim+ SP::F0, SP::F1, SP::F2, SP::F3, 319263320Sdim+ SP::F4, SP::F5, SP::F6, SP::F7, 320263320Sdim+ SP::F8, SP::F9, SP::F10, SP::F11, 321263320Sdim+ SP::F12, SP::F13, SP::F14, SP::F15, 322263320Sdim+ SP::F16, SP::F17, SP::F18, SP::F19, 323263320Sdim+ SP::F20, SP::F21, SP::F22, SP::F23, 324263320Sdim+ SP::F24, SP::F25, SP::F26, SP::F27, 325263320Sdim+ SP::F28, SP::F29, SP::F30, SP::F31 }; 326263320Sdim+ 327263320Sdim+static const unsigned DFPRegDecoderTable[] = { 328263320Sdim+ SP::D0, SP::D16, SP::D1, SP::D17, 329263320Sdim+ SP::D2, SP::D18, SP::D3, SP::D19, 330263320Sdim+ SP::D4, SP::D20, SP::D5, SP::D21, 331263320Sdim+ SP::D6, SP::D22, SP::D7, SP::D23, 332263320Sdim+ SP::D8, SP::D24, SP::D9, SP::D25, 333263320Sdim+ SP::D10, SP::D26, SP::D11, SP::D27, 334263320Sdim+ SP::D12, SP::D28, SP::D13, SP::D29, 335263320Sdim+ SP::D14, SP::D30, SP::D15, SP::D31 }; 336263320Sdim+ 337263320Sdim+static const unsigned QFPRegDecoderTable[] = { 338263320Sdim+ SP::Q0, SP::Q8, -1, -1, 339263320Sdim+ SP::Q1, SP::Q9, -1, -1, 340263320Sdim+ SP::Q2, SP::Q10, -1, -1, 341263320Sdim+ SP::Q3, SP::Q11, -1, -1, 342263320Sdim+ SP::Q4, SP::Q12, -1, -1, 343263320Sdim+ SP::Q5, SP::Q13, -1, -1, 344263320Sdim+ SP::Q6, SP::Q14, -1, -1, 345263320Sdim+ SP::Q7, SP::Q15, -1, -1 } ; 346263320Sdim+ 347263320Sdim+static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, 348263320Sdim+ unsigned RegNo, 349263320Sdim+ uint64_t Address, 350263320Sdim+ const void *Decoder) { 351263320Sdim+ if (RegNo > 31) 352263320Sdim+ return MCDisassembler::Fail; 353263320Sdim+ unsigned Reg = IntRegDecoderTable[RegNo]; 354263320Sdim+ Inst.addOperand(MCOperand::CreateReg(Reg)); 355263320Sdim+ return MCDisassembler::Success; 356263320Sdim+} 357263320Sdim+ 358263320Sdim+static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, 359263320Sdim+ unsigned RegNo, 360263320Sdim+ uint64_t Address, 361263320Sdim+ const void *Decoder) { 362263320Sdim+ if (RegNo > 31) 363263320Sdim+ return MCDisassembler::Fail; 364263320Sdim+ unsigned Reg = IntRegDecoderTable[RegNo]; 365263320Sdim+ Inst.addOperand(MCOperand::CreateReg(Reg)); 366263320Sdim+ return MCDisassembler::Success; 367263320Sdim+} 368263320Sdim+ 369263320Sdim+ 370263320Sdim+static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, 371263320Sdim+ unsigned RegNo, 372263320Sdim+ uint64_t Address, 373263320Sdim+ const void *Decoder) { 374263320Sdim+ if (RegNo > 31) 375263320Sdim+ return MCDisassembler::Fail; 376263320Sdim+ unsigned Reg = FPRegDecoderTable[RegNo]; 377263320Sdim+ Inst.addOperand(MCOperand::CreateReg(Reg)); 378263320Sdim+ return MCDisassembler::Success; 379263320Sdim+} 380263320Sdim+ 381263320Sdim+ 382263320Sdim+static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, 383263320Sdim+ unsigned RegNo, 384263320Sdim+ uint64_t Address, 385263320Sdim+ const void *Decoder) { 386263320Sdim+ if (RegNo > 31) 387263320Sdim+ return MCDisassembler::Fail; 388263320Sdim+ unsigned Reg = DFPRegDecoderTable[RegNo]; 389263320Sdim+ Inst.addOperand(MCOperand::CreateReg(Reg)); 390263320Sdim+ return MCDisassembler::Success; 391263320Sdim+} 392263320Sdim+ 393263320Sdim+ 394263320Sdim+static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, 395263320Sdim+ unsigned RegNo, 396263320Sdim+ uint64_t Address, 397263320Sdim+ const void *Decoder) { 398263320Sdim+ if (RegNo > 31) 399263320Sdim+ return MCDisassembler::Fail; 400263320Sdim+ 401263320Sdim+ unsigned Reg = QFPRegDecoderTable[RegNo]; 402263320Sdim+ if (Reg == (unsigned)-1) 403263320Sdim+ return MCDisassembler::Fail; 404263320Sdim+ Inst.addOperand(MCOperand::CreateReg(Reg)); 405263320Sdim+ return MCDisassembler::Success; 406263320Sdim+} 407263320Sdim+ 408263320Sdim+ 409263320Sdim+#include "SparcGenDisassemblerTables.inc" 410263320Sdim+ 411263320Sdim+/// readInstruction - read four bytes from the MemoryObject 412263320Sdim+/// and return 32 bit word. 413263320Sdim+static DecodeStatus readInstruction32(const MemoryObject ®ion, 414263320Sdim+ uint64_t address, 415263320Sdim+ uint64_t &size, 416263320Sdim+ uint32_t &insn) { 417263320Sdim+ uint8_t Bytes[4]; 418263320Sdim+ 419263320Sdim+ // We want to read exactly 4 Bytes of data. 420263320Sdim+ if (region.readBytes(address, 4, Bytes) == -1) { 421263320Sdim+ size = 0; 422263320Sdim+ return MCDisassembler::Fail; 423263320Sdim+ } 424263320Sdim+ 425263320Sdim+ // Encoded as a big-endian 32-bit word in the stream. 426263320Sdim+ insn = (Bytes[3] << 0) | 427263320Sdim+ (Bytes[2] << 8) | 428263320Sdim+ (Bytes[1] << 16) | 429263320Sdim+ (Bytes[0] << 24); 430263320Sdim+ 431263320Sdim+ return MCDisassembler::Success; 432263320Sdim+} 433263320Sdim+ 434263320Sdim+ 435263320Sdim+DecodeStatus 436263320Sdim+SparcDisassembler::getInstruction(MCInst &instr, 437263320Sdim+ uint64_t &Size, 438263320Sdim+ const MemoryObject &Region, 439263320Sdim+ uint64_t Address, 440263320Sdim+ raw_ostream &vStream, 441263320Sdim+ raw_ostream &cStream) const { 442263320Sdim+ uint32_t Insn; 443263320Sdim+ 444263320Sdim+ DecodeStatus Result = readInstruction32(Region, Address, Size, Insn); 445263320Sdim+ if (Result == MCDisassembler::Fail) 446263320Sdim+ return MCDisassembler::Fail; 447263320Sdim+ 448263320Sdim+ 449263320Sdim+ // Calling the auto-generated decoder function. 450263320Sdim+ Result = decodeInstruction(DecoderTableSparc32, instr, Insn, Address, 451263320Sdim+ this, STI); 452263320Sdim+ 453263320Sdim+ if (Result != MCDisassembler::Fail) { 454263320Sdim+ Size = 4; 455263320Sdim+ return Result; 456263320Sdim+ } 457263320Sdim+ 458263320Sdim+ return MCDisassembler::Fail; 459263320Sdim+} 460263320SdimIndex: lib/Target/Sparc/Disassembler/LLVMBuild.txt 461263320Sdim=================================================================== 462263320Sdim--- lib/Target/Sparc/Disassembler/LLVMBuild.txt 463263320Sdim+++ lib/Target/Sparc/Disassembler/LLVMBuild.txt 464263320Sdim@@ -0,0 +1,23 @@ 465263320Sdim+;===- ./lib/Target/Sparc/Disassembler/LLVMBuild.txt ------------*- Conf -*--===; 466263320Sdim+; 467263320Sdim+; The LLVM Compiler Infrastructure 468263320Sdim+; 469263320Sdim+; This file is distributed under the University of Illinois Open Source 470263320Sdim+; License. See LICENSE.TXT for details. 471263320Sdim+; 472263320Sdim+;===------------------------------------------------------------------------===; 473263320Sdim+; 474263320Sdim+; This is an LLVMBuild description file for the components in this subdirectory. 475263320Sdim+; 476263320Sdim+; For more information on the LLVMBuild system, please see: 477263320Sdim+; 478263320Sdim+; http://llvm.org/docs/LLVMBuild.html 479263320Sdim+; 480263320Sdim+;===------------------------------------------------------------------------===; 481263320Sdim+ 482263320Sdim+[component_0] 483263320Sdim+type = Library 484263320Sdim+name = SparcDisassembler 485263320Sdim+parent = Sparc 486263320Sdim+required_libraries = MC Support SparcInfo 487263320Sdim+add_to_library_groups = Sparc 488263320SdimIndex: lib/Target/Sparc/Disassembler/CMakeLists.txt 489263320Sdim=================================================================== 490263320Sdim--- lib/Target/Sparc/Disassembler/CMakeLists.txt 491263320Sdim+++ lib/Target/Sparc/Disassembler/CMakeLists.txt 492263320Sdim@@ -0,0 +1,12 @@ 493263320Sdim+add_llvm_library(LLVMSparcDisassembler 494263320Sdim+ SparcDisassembler.cpp 495263320Sdim+ ) 496263320Sdim+ 497263320Sdim+# workaround for hanging compilation on MSVC9 and 10 498263320Sdim+if( MSVC_VERSION EQUAL 1400 OR MSVC_VERSION EQUAL 1500 499263320Sdim+ OR MSVC_VERSION EQUAL 1600 ) 500263320Sdim+set_property( 501263320Sdim+ SOURCE SparcDisassembler.cpp 502263320Sdim+ PROPERTY COMPILE_FLAGS "/Od" 503263320Sdim+ ) 504263320Sdim+endif() 505263320SdimIndex: lib/Target/Sparc/Disassembler/Makefile 506263320Sdim=================================================================== 507263320Sdim--- lib/Target/Sparc/Disassembler/Makefile 508263320Sdim+++ lib/Target/Sparc/Disassembler/Makefile 509263320Sdim@@ -0,0 +1,16 @@ 510263320Sdim+##===- lib/Target/Sparc/Disassembler/Makefile --------------*- Makefile -*-===## 511263320Sdim+# 512263320Sdim+# The LLVM Compiler Infrastructure 513263320Sdim+# 514263320Sdim+# This file is distributed under the University of Illinois Open Source 515263320Sdim+# License. See LICENSE.TXT for details. 516263320Sdim+# 517263320Sdim+##===----------------------------------------------------------------------===## 518263320Sdim+ 519263320Sdim+LEVEL = ../../../.. 520263320Sdim+LIBRARYNAME = LLVMSparcDisassembler 521263320Sdim+ 522263320Sdim+# Hack: we need to include 'main' Sparc target directory to grab private headers 523263320Sdim+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. 524263320Sdim+ 525263320Sdim+include $(LEVEL)/Makefile.common 526263320SdimIndex: lib/Target/Sparc/Makefile 527263320Sdim=================================================================== 528263320Sdim--- lib/Target/Sparc/Makefile 529263320Sdim+++ lib/Target/Sparc/Makefile 530263320Sdim@@ -14,11 +14,11 @@ TARGET = Sparc 531263320Sdim # Make sure that tblgen is run, first thing. 532263320Sdim BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenInstrInfo.inc \ 533263320Sdim SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \ 534263320Sdim- SparcGenDAGISel.inc \ 535263320Sdim+ SparcGenDAGISel.inc SparcGenDisassemblerTables.inc \ 536263320Sdim SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \ 537263320Sdim SparcGenCodeEmitter.inc SparcGenMCCodeEmitter.inc 538263320Sdim 539263320Sdim-DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc 540263320Sdim+DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc 541263320Sdim 542263320Sdim include $(LEVEL)/Makefile.common 543263320Sdim 544263320SdimIndex: lib/Target/Sparc/SparcInstr64Bit.td 545263320Sdim=================================================================== 546263320Sdim--- lib/Target/Sparc/SparcInstr64Bit.td 547263320Sdim+++ lib/Target/Sparc/SparcInstr64Bit.td 548263320Sdim@@ -141,6 +141,7 @@ def : Pat<(i64 imm:$val), 549263320Sdim let Predicates = [Is64Bit] in { 550263320Sdim 551263320Sdim // Register-register instructions. 552263320Sdim+let isCodeGenOnly = 1 in { 553263320Sdim defm ANDX : F3_12<"and", 0b000001, and, I64Regs, i64, i64imm>; 554263320Sdim defm ORX : F3_12<"or", 0b000010, or, I64Regs, i64, i64imm>; 555263320Sdim defm XORX : F3_12<"xor", 0b000011, xor, I64Regs, i64, i64imm>; 556263320Sdim@@ -161,8 +162,6 @@ def XNORXrr : F3_1<2, 0b000111, 557263320Sdim defm ADDX : F3_12<"add", 0b000000, add, I64Regs, i64, i64imm>; 558263320Sdim defm SUBX : F3_12<"sub", 0b000100, sub, I64Regs, i64, i64imm>; 559263320Sdim 560263320Sdim-def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>; 561263320Sdim- 562263320Sdim def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$rd), 563263320Sdim (ins I64Regs:$rs1, I64Regs:$rs2, TLSSym:$sym), 564263320Sdim "add $rs1, $rs2, $rd, $sym", 565263320Sdim@@ -169,18 +168,17 @@ def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$ 566263320Sdim [(set i64:$rd, 567263320Sdim (tlsadd i64:$rs1, i64:$rs2, tglobaltlsaddr:$sym))]>; 568263320Sdim 569263320Sdim-// Register-immediate instructions. 570263320Sdim- 571263320Sdim-def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>; 572263320Sdim- 573263320Sdim-def : Pat<(ctpop i64:$src), (POPCrr $src)>; 574263320Sdim- 575263320Sdim // "LEA" form of add 576263320Sdim-let isCodeGenOnly = 1 in 577263320Sdim def LEAX_ADDri : F3_2<2, 0b000000, 578263320Sdim (outs I64Regs:$dst), (ins MEMri:$addr), 579263320Sdim "add ${addr:arith}, $dst", 580263320Sdim [(set iPTR:$dst, ADDRri:$addr)]>; 581263320Sdim+} 582263320Sdim+ 583263320Sdim+def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>; 584263320Sdim+def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>; 585263320Sdim+def : Pat<(ctpop i64:$src), (POPCrr $src)>; 586263320Sdim+ 587263320Sdim } // Predicates = [Is64Bit] 588263320Sdim 589263320Sdim 590263320Sdim@@ -245,7 +243,7 @@ def LDXri : F3_2<3, 0b001011, 591263320Sdim (outs I64Regs:$dst), (ins MEMri:$addr), 592263320Sdim "ldx [$addr], $dst", 593263320Sdim [(set i64:$dst, (load ADDRri:$addr))]>; 594263320Sdim-let mayLoad = 1 in 595263320Sdim+let mayLoad = 1, isCodeGenOnly = 1, isAsmParserOnly = 1 in 596263320Sdim def TLS_LDXrr : F3_1<3, 0b001011, 597263320Sdim (outs IntRegs:$dst), (ins MEMrr:$addr, TLSSym:$sym), 598263320Sdim "ldx [$addr], $dst, $sym", 599263320Sdim@@ -278,11 +276,11 @@ def : Pat<(i64 (extloadi32 ADDRrr:$addr)), (LDrr 600263320Sdim def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri ADDRri:$addr)>; 601263320Sdim 602263320Sdim // Sign-extending load of i32 into i64 is a new SPARC v9 instruction. 603263320Sdim-def LDSWrr : F3_1<3, 0b001011, 604263320Sdim+def LDSWrr : F3_1<3, 0b001000, 605263320Sdim (outs I64Regs:$dst), (ins MEMrr:$addr), 606263320Sdim "ldsw [$addr], $dst", 607263320Sdim [(set i64:$dst, (sextloadi32 ADDRrr:$addr))]>; 608263320Sdim-def LDSWri : F3_2<3, 0b001011, 609263320Sdim+def LDSWri : F3_2<3, 0b001000, 610263320Sdim (outs I64Regs:$dst), (ins MEMri:$addr), 611263320Sdim "ldsw [$addr], $dst", 612263320Sdim [(set i64:$dst, (sextloadi32 ADDRri:$addr))]>; 613263320Sdim@@ -289,13 +287,13 @@ def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri 614263320Sdim 615263320Sdim // 64-bit stores. 616263320Sdim def STXrr : F3_1<3, 0b001110, 617263320Sdim- (outs), (ins MEMrr:$addr, I64Regs:$src), 618263320Sdim- "stx $src, [$addr]", 619263320Sdim- [(store i64:$src, ADDRrr:$addr)]>; 620263320Sdim+ (outs), (ins MEMrr:$addr, I64Regs:$rd), 621263320Sdim+ "stx $rd, [$addr]", 622263320Sdim+ [(store i64:$rd, ADDRrr:$addr)]>; 623263320Sdim def STXri : F3_2<3, 0b001110, 624263320Sdim- (outs), (ins MEMri:$addr, I64Regs:$src), 625263320Sdim- "stx $src, [$addr]", 626263320Sdim- [(store i64:$src, ADDRri:$addr)]>; 627263320Sdim+ (outs), (ins MEMri:$addr, I64Regs:$rd), 628263320Sdim+ "stx $rd, [$addr]", 629263320Sdim+ [(store i64:$rd, ADDRri:$addr)]>; 630263320Sdim 631263320Sdim // Truncating stores from i64 are identical to the i32 stores. 632263320Sdim def : Pat<(truncstorei8 i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>; 633263320Sdim@@ -315,6 +313,15 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADD 634263320Sdim //===----------------------------------------------------------------------===// 635263320Sdim // 64-bit Conditionals. 636263320Sdim //===----------------------------------------------------------------------===// 637263320Sdim+ 638263320Sdim+// Conditional branch class on %xcc: 639263320Sdim+class XBranchSP<dag ins, string asmstr, list<dag> pattern> 640263320Sdim+ : F2_3<0b001, 0b10, (outs), ins, asmstr, pattern> { 641263320Sdim+ let isBranch = 1; 642263320Sdim+ let isTerminator = 1; 643263320Sdim+ let hasDelaySlot = 1; 644263320Sdim+} 645263320Sdim+ 646263320Sdim // 647263320Sdim // Flag-setting instructions like subcc and addcc set both icc and xcc flags. 648263320Sdim // The icc flags correspond to the 32-bit result, and the xcc are for the 649263320Sdim@@ -326,7 +333,7 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADD 650263320Sdim let Predicates = [Is64Bit] in { 651263320Sdim 652263320Sdim let Uses = [ICC] in 653263320Sdim-def BPXCC : BranchSP<(ins brtarget:$imm22, CCOp:$cond), 654263320Sdim+def BPXCC : XBranchSP<(ins brtarget:$imm22, CCOp:$cond), 655263320Sdim "b$cond %xcc, $imm22", 656263320Sdim [(SPbrxcc bb:$imm22, imm:$cond)]>; 657263320Sdim 658263320Sdim@@ -409,7 +416,7 @@ def : Pat<(SPselectfcc (i64 simm11:$t), i64:$f, im 659263320Sdim 660263320Sdim 661263320Sdim // 64 bit SETHI 662263320Sdim-let Predicates = [Is64Bit] in { 663263320Sdim+let Predicates = [Is64Bit], isCodeGenOnly = 1 in { 664263320Sdim def SETHIXi : F2_1<0b100, 665263320Sdim (outs IntRegs:$rd), (ins i64imm:$imm22), 666263320Sdim "sethi $imm22, $rd", 667263320SdimIndex: test/MC/Disassembler/Sparc/lit.local.cfg 668263320Sdim=================================================================== 669263320Sdim--- test/MC/Disassembler/Sparc/lit.local.cfg 670263320Sdim+++ test/MC/Disassembler/Sparc/lit.local.cfg 671263320Sdim@@ -0,0 +1,4 @@ 672263320Sdim+targets = set(config.root.targets_to_build.split()) 673263320Sdim+if not 'Sparc' in targets: 674263320Sdim+ config.unsupported = True 675263320Sdim+ 676263320SdimIndex: test/MC/Disassembler/Sparc/sparc.txt 677263320Sdim=================================================================== 678263320Sdim--- test/MC/Disassembler/Sparc/sparc.txt 679263320Sdim+++ test/MC/Disassembler/Sparc/sparc.txt 680263320Sdim@@ -0,0 +1,82 @@ 681263320Sdim+# RUN: llvm-mc --disassemble %s -triple=sparc-unknown-linux | FileCheck %s 682263320Sdim+ 683263320Sdim+# CHECK: add %g0, %g0, %g0 684263320Sdim+0x80 0x00 0x00 0x00 685263320Sdim+ 686263320Sdim+# CHECK: add %g1, %g2, %g3 687263320Sdim+0x86 0x00 0x40 0x02 688263320Sdim+ 689263320Sdim+# CHECK: add %o0, %o1, %l0 690263320Sdim+0xa0 0x02 0x00 0x09 691263320Sdim+ 692263320Sdim+# CHECK: add %o0, 10, %l0 693263320Sdim+0xa0 0x02 0x20 0x0a 694263320Sdim+ 695263320Sdim+# CHECK: addcc %g1, %g2, %g3 696263320Sdim+0x86 0x80 0x40 0x02 697263320Sdim+ 698263320Sdim+# CHECK: addxcc %g1, %g2, %g3 699263320Sdim+0x86 0xc0 0x40 0x02 700263320Sdim+ 701263320Sdim+# CHECK: udiv %g1, %g2, %g3 702263320Sdim+0x86 0x70 0x40 0x02 703263320Sdim+ 704263320Sdim+# CHECK: sdiv %g1, %g2, %g3 705263320Sdim+0x86 0x78 0x40 0x02 706263320Sdim+ 707263320Sdim+# CHECK: and %g1, %g2, %g3 708263320Sdim+0x86 0x08 0x40 0x02 709263320Sdim+ 710263320Sdim+# CHECK: andn %g1, %g2, %g3 711263320Sdim+0x86 0x28 0x40 0x02 712263320Sdim+ 713263320Sdim+# CHECK: or %g1, %g2, %g3 714263320Sdim+0x86 0x10 0x40 0x02 715263320Sdim+ 716263320Sdim+# CHECK: orn %g1, %g2, %g3 717263320Sdim+0x86 0x30 0x40 0x02 718263320Sdim+ 719263320Sdim+# CHECK: xor %g1, %g2, %g3 720263320Sdim+0x86 0x18 0x40 0x02 721263320Sdim+ 722263320Sdim+# CHECK: xnor %g1, %g2, %g3 723263320Sdim+0x86 0x38 0x40 0x02 724263320Sdim+ 725263320Sdim+# CHECK: umul %g1, %g2, %g3 726263320Sdim+0x86 0x50 0x40 0x02 727263320Sdim+ 728263320Sdim+# CHECK: smul %g1, %g2, %g3 729263320Sdim+0x86 0x58 0x40 0x02 730263320Sdim+ 731263320Sdim+# CHECK: nop 732263320Sdim+0x01 0x00 0x00 0x00 733263320Sdim+ 734263320Sdim+# CHECK: sethi 10, %l0 735263320Sdim+0x21 0x00 0x00 0x0a 736263320Sdim+ 737263320Sdim+# CHECK: sll %g1, %g2, %g3 738263320Sdim+0x87 0x28 0x40 0x02 739263320Sdim+ 740263320Sdim+# CHECK: sll %g1, 31, %g3 741263320Sdim+0x87 0x28 0x60 0x1f 742263320Sdim+ 743263320Sdim+# CHECK: srl %g1, %g2, %g3 744263320Sdim+0x87 0x30 0x40 0x02 745263320Sdim+ 746263320Sdim+# CHECK: srl %g1, 31, %g3 747263320Sdim+0x87 0x30 0x60 0x1f 748263320Sdim+ 749263320Sdim+# CHECK: sra %g1, %g2, %g3 750263320Sdim+0x87 0x38 0x40 0x02 751263320Sdim+ 752263320Sdim+# CHECK: sra %g1, 31, %g3 753263320Sdim+0x87 0x38 0x60 0x1f 754263320Sdim+ 755263320Sdim+# CHECK: sub %g1, %g2, %g3 756263320Sdim+0x86 0x20 0x40 0x02 757263320Sdim+ 758263320Sdim+# CHECK: subcc %g1, %g2, %g3 759263320Sdim+0x86 0xa0 0x40 0x02 760263320Sdim+ 761263320Sdim+# CHECK: subxcc %g1, %g2, %g3 762263320Sdim+0x86 0xe0 0x40 0x02 763