patch-r262261-llvm-r198533-sparc.diff revision 269012
1Pull in r198533 from upstream llvm trunk (by Venkatraman Govindaraju): 2 3 [Sparc] Add initial implementation of MC Code emitter for sparc. 4 5Introduced here: http://svnweb.freebsd.org/changeset/base/262261 6 7Index: lib/Target/Sparc/SparcInstrInfo.td 8=================================================================== 9--- lib/Target/Sparc/SparcInstrInfo.td 10+++ lib/Target/Sparc/SparcInstrInfo.td 11@@ -100,9 +100,14 @@ def MEMri : Operand<iPTR> { 12 def TLSSym : Operand<iPTR>; 13 14 // Branch targets have OtherVT type. 15-def brtarget : Operand<OtherVT>; 16-def calltarget : Operand<i32>; 17+def brtarget : Operand<OtherVT> { 18+ let EncoderMethod = "getBranchTargetOpValue"; 19+} 20 21+def calltarget : Operand<i32> { 22+ let EncoderMethod = "getCallTargetOpValue"; 23+} 24+ 25 // Operand for printing out a condition code. 26 let PrintMethod = "printCCOperand" in 27 def CCOp : Operand<i32>; 28Index: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt 29=================================================================== 30--- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt 31+++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt 32@@ -1,6 +1,8 @@ 33 add_llvm_library(LLVMSparcDesc 34+ SparcAsmBackend.cpp 35+ SparcMCAsmInfo.cpp 36+ SparcMCCodeEmitter.cpp 37 SparcMCTargetDesc.cpp 38- SparcMCAsmInfo.cpp 39 SparcMCExpr.cpp 40 SparcTargetStreamer.cpp 41 ) 42Index: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp 43=================================================================== 44--- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp 45+++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp 46@@ -0,0 +1,131 @@ 47+//===-- SparcMCCodeEmitter.cpp - Convert Sparc code to machine code -------===// 48+// 49+// The LLVM Compiler Infrastructure 50+// 51+// This file is distributed under the University of Illinois Open Source 52+// License. See LICENSE.TXT for details. 53+// 54+//===----------------------------------------------------------------------===// 55+// 56+// This file implements the SparcMCCodeEmitter class. 57+// 58+//===----------------------------------------------------------------------===// 59+ 60+#define DEBUG_TYPE "mccodeemitter" 61+#include "SparcMCTargetDesc.h" 62+#include "MCTargetDesc/SparcFixupKinds.h" 63+#include "llvm/MC/MCCodeEmitter.h" 64+#include "llvm/MC/MCContext.h" 65+#include "llvm/MC/MCExpr.h" 66+#include "llvm/MC/MCInst.h" 67+#include "llvm/MC/MCRegisterInfo.h" 68+#include "llvm/ADT/Statistic.h" 69+#include "llvm/Support/raw_ostream.h" 70+ 71+using namespace llvm; 72+ 73+STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 74+ 75+namespace { 76+class SparcMCCodeEmitter : public MCCodeEmitter { 77+ SparcMCCodeEmitter(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION; 78+ void operator=(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION; 79+ MCContext &Ctx; 80+ 81+public: 82+ SparcMCCodeEmitter(MCContext &ctx): Ctx(ctx) {} 83+ 84+ ~SparcMCCodeEmitter() {} 85+ 86+ void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 87+ SmallVectorImpl<MCFixup> &Fixups) const; 88+ 89+ // getBinaryCodeForInstr - TableGen'erated function for getting the 90+ // binary encoding for an instruction. 91+ uint64_t getBinaryCodeForInstr(const MCInst &MI, 92+ SmallVectorImpl<MCFixup> &Fixups) const; 93+ 94+ /// getMachineOpValue - Return binary encoding of operand. If the machine 95+ /// operand requires relocation, record the relocation and return zero. 96+ unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 97+ SmallVectorImpl<MCFixup> &Fixups) const; 98+ 99+ unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo, 100+ SmallVectorImpl<MCFixup> &Fixups) const; 101+ unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 102+ SmallVectorImpl<MCFixup> &Fixups) const; 103+ 104+}; 105+} // end anonymous namespace 106+ 107+MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII, 108+ const MCRegisterInfo &MRI, 109+ const MCSubtargetInfo &STI, 110+ MCContext &Ctx) { 111+ return new SparcMCCodeEmitter(Ctx); 112+} 113+ 114+void SparcMCCodeEmitter:: 115+EncodeInstruction(const MCInst &MI, raw_ostream &OS, 116+ SmallVectorImpl<MCFixup> &Fixups) const { 117+ unsigned Bits = getBinaryCodeForInstr(MI, Fixups); 118+ 119+ // Output the constant in big endian byte order. 120+ for (unsigned i = 0; i != 4; ++i) { 121+ OS << (char)(Bits >> 24); 122+ Bits <<= 8; 123+ } 124+ 125+ ++MCNumEmitted; // Keep track of the # of mi's emitted. 126+} 127+ 128+ 129+unsigned SparcMCCodeEmitter:: 130+getMachineOpValue(const MCInst &MI, const MCOperand &MO, 131+ SmallVectorImpl<MCFixup> &Fixups) const { 132+ 133+ if (MO.isReg()) 134+ return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 135+ 136+ if (MO.isImm()) 137+ return MO.getImm(); 138+ 139+ assert(MO.isExpr()); 140+ const MCExpr *Expr = MO.getExpr(); 141+ int64_t Res; 142+ if (Expr->EvaluateAsAbsolute(Res)) 143+ return Res; 144+ 145+ assert(0 && "Unhandled expression!"); 146+ return 0; 147+} 148+ 149+unsigned SparcMCCodeEmitter:: 150+getCallTargetOpValue(const MCInst &MI, unsigned OpNo, 151+ SmallVectorImpl<MCFixup> &Fixups) const { 152+ const MCOperand &MO = MI.getOperand(OpNo); 153+ if (MO.isReg() || MO.isImm()) 154+ return getMachineOpValue(MI, MO, Fixups); 155+ 156+ Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 157+ (MCFixupKind)Sparc::fixup_sparc_call30)); 158+ return 0; 159+} 160+ 161+unsigned SparcMCCodeEmitter:: 162+getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 163+ SmallVectorImpl<MCFixup> &Fixups) const { 164+ const MCOperand &MO = MI.getOperand(OpNo); 165+ if (MO.isReg() || MO.isImm()) 166+ return getMachineOpValue(MI, MO, Fixups); 167+ 168+ Sparc::Fixups fixup = Sparc::fixup_sparc_br22; 169+ if (MI.getOpcode() == SP::BPXCC) 170+ fixup = Sparc::fixup_sparc_br19; 171+ 172+ Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 173+ (MCFixupKind)fixup)); 174+ return 0; 175+} 176+ 177+#include "SparcGenMCCodeEmitter.inc" 178Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp 179=================================================================== 180--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp 181+++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp 182@@ -136,6 +136,18 @@ extern "C" void LLVMInitializeSparcTargetMC() { 183 TargetRegistry::RegisterMCSubtargetInfo(TheSparcV9Target, 184 createSparcMCSubtargetInfo); 185 186+ // Register the MC Code Emitter. 187+ TargetRegistry::RegisterMCCodeEmitter(TheSparcTarget, 188+ createSparcMCCodeEmitter); 189+ TargetRegistry::RegisterMCCodeEmitter(TheSparcV9Target, 190+ createSparcMCCodeEmitter); 191+ 192+ //Register the asm backend. 193+ TargetRegistry::RegisterMCAsmBackend(TheSparcTarget, 194+ createSparcAsmBackend); 195+ TargetRegistry::RegisterMCAsmBackend(TheSparcV9Target, 196+ createSparcAsmBackend); 197+ 198 TargetRegistry::RegisterAsmStreamer(TheSparcTarget, 199 createMCAsmStreamer); 200 TargetRegistry::RegisterAsmStreamer(TheSparcV9Target, 201Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp 202=================================================================== 203--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp 204+++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp 205@@ -0,0 +1,101 @@ 206+//===-- SparcAsmBackend.cpp - Sparc Assembler Backend ---------------------===// 207+// 208+// The LLVM Compiler Infrastructure 209+// 210+// This file is distributed under the University of Illinois Open Source 211+// License. See LICENSE.TXT for details. 212+// 213+//===----------------------------------------------------------------------===// 214+ 215+#include "llvm/MC/MCAsmBackend.h" 216+#include "MCTargetDesc/SparcMCTargetDesc.h" 217+#include "MCTargetDesc/SparcFixupKinds.h" 218+#include "llvm/MC/MCFixupKindInfo.h" 219+#include "llvm/MC/MCObjectWriter.h" 220+#include "llvm/Support/TargetRegistry.h" 221+ 222+using namespace llvm; 223+ 224+namespace { 225+ class SparcAsmBackend : public MCAsmBackend { 226+ 227+ public: 228+ SparcAsmBackend(const Target &T) : MCAsmBackend() {} 229+ 230+ unsigned getNumFixupKinds() const { 231+ return Sparc::NumTargetFixupKinds; 232+ } 233+ 234+ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { 235+ const static MCFixupKindInfo Infos[Sparc::NumTargetFixupKinds] = { 236+ // name offset bits flags 237+ { "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel }, 238+ { "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel }, 239+ { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel } 240+ }; 241+ 242+ if (Kind < FirstTargetFixupKind) 243+ return MCAsmBackend::getFixupKindInfo(Kind); 244+ 245+ assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 246+ "Invalid kind!"); 247+ return Infos[Kind - FirstTargetFixupKind]; 248+ } 249+ 250+ bool mayNeedRelaxation(const MCInst &Inst) const { 251+ // FIXME. 252+ return false; 253+ } 254+ 255+ /// fixupNeedsRelaxation - Target specific predicate for whether a given 256+ /// fixup requires the associated instruction to be relaxed. 257+ bool fixupNeedsRelaxation(const MCFixup &Fixup, 258+ uint64_t Value, 259+ const MCRelaxableFragment *DF, 260+ const MCAsmLayout &Layout) const { 261+ // FIXME. 262+ assert(0 && "fixupNeedsRelaxation() unimplemented"); 263+ return false; 264+ } 265+ void relaxInstruction(const MCInst &Inst, MCInst &Res) const { 266+ // FIXME. 267+ assert(0 && "relaxInstruction() unimplemented"); 268+ } 269+ 270+ bool writeNopData(uint64_t Count, MCObjectWriter *OW) const { 271+ // FIXME: Zero fill for now. 272+ for (uint64_t i = 0; i != Count; ++i) 273+ OW->Write8(0); 274+ return true; 275+ } 276+ }; 277+ 278+ class ELFSparcAsmBackend : public SparcAsmBackend { 279+ public: 280+ ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) : 281+ SparcAsmBackend(T) { } 282+ 283+ void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 284+ uint64_t Value) const { 285+ assert(0 && "applyFixup not implemented yet"); 286+ } 287+ 288+ MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 289+ assert(0 && "Object Writer not implemented yet"); 290+ return 0; 291+ } 292+ 293+ virtual bool doesSectionRequireSymbols(const MCSection &Section) const { 294+ return false; 295+ } 296+ }; 297+ 298+} // end anonymous namespace 299+ 300+ 301+MCAsmBackend *llvm::createSparcAsmBackend(const Target &T, 302+ const MCRegisterInfo &MRI, 303+ StringRef TT, 304+ StringRef CPU) { 305+ return new ELFSparcAsmBackend(T, Triple(TT).getOS()); 306+} 307Index: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h 308=================================================================== 309--- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h 310+++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h 311@@ -0,0 +1,36 @@ 312+//===-- SparcFixupKinds.h - Sparc Specific Fixup Entries --------*- C++ -*-===// 313+// 314+// The LLVM Compiler Infrastructure 315+// 316+// This file is distributed under the University of Illinois Open Source 317+// License. See LICENSE.TXT for details. 318+// 319+//===----------------------------------------------------------------------===// 320+ 321+#ifndef LLVM_SPARC_FIXUPKINDS_H 322+#define LLVM_SPARC_FIXUPKINDS_H 323+ 324+#include "llvm/MC/MCFixup.h" 325+ 326+namespace llvm { 327+ namespace Sparc { 328+ enum Fixups { 329+ // fixup_sparc_call30 - 30-bit PC relative relocation for call 330+ fixup_sparc_call30 = FirstTargetFixupKind, 331+ 332+ /// fixup_sparc_br22 - 22-bit PC relative relocation for 333+ /// branches 334+ fixup_sparc_br22, 335+ 336+ /// fixup_sparc_br22 - 22-bit PC relative relocation for 337+ /// branches on icc/xcc 338+ fixup_sparc_br19, 339+ 340+ // Marker 341+ LastTargetFixupKind, 342+ NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind 343+ }; 344+ } 345+} 346+ 347+#endif 348Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h 349=================================================================== 350--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h 351+++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h 352@@ -15,11 +15,27 @@ 353 #define SPARCMCTARGETDESC_H 354 355 namespace llvm { 356+class MCAsmBackend; 357+class MCCodeEmitter; 358+class MCContext; 359+class MCInstrInfo; 360+class MCRegisterInfo; 361+class MCSubtargetInfo; 362 class Target; 363+class StringRef; 364 365 extern Target TheSparcTarget; 366 extern Target TheSparcV9Target; 367 368+MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII, 369+ const MCRegisterInfo &MRI, 370+ const MCSubtargetInfo &STI, 371+ MCContext &Ctx); 372+MCAsmBackend *createSparcAsmBackend(const Target &T, 373+ const MCRegisterInfo &MRI, 374+ StringRef TT, 375+ StringRef CPU); 376+ 377 } // End llvm namespace 378 379 // Defines symbolic names for Sparc registers. This defines a mapping from 380Index: lib/Target/Sparc/Makefile 381=================================================================== 382--- lib/Target/Sparc/Makefile 383+++ lib/Target/Sparc/Makefile 384@@ -16,7 +16,7 @@ BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenI 385 SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \ 386 SparcGenDAGISel.inc \ 387 SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \ 388- SparcGenCodeEmitter.inc 389+ SparcGenCodeEmitter.inc SparcGenMCCodeEmitter.inc 390 391 DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc 392 393Index: lib/Target/Sparc/CMakeLists.txt 394=================================================================== 395--- lib/Target/Sparc/CMakeLists.txt 396+++ lib/Target/Sparc/CMakeLists.txt 397@@ -3,6 +3,7 @@ set(LLVM_TARGET_DEFINITIONS Sparc.td) 398 tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info) 399 tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info) 400 tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter) 401+tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter -mc-emitter) 402 tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer) 403 tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher) 404 tablegen(LLVM SparcGenDAGISel.inc -gen-dag-isel) 405Index: lib/Target/Sparc/SparcCodeEmitter.cpp 406=================================================================== 407--- lib/Target/Sparc/SparcCodeEmitter.cpp 408+++ lib/Target/Sparc/SparcCodeEmitter.cpp 409@@ -72,6 +72,11 @@ class SparcCodeEmitter : public MachineFunctionPas 410 unsigned getMachineOpValue(const MachineInstr &MI, 411 const MachineOperand &MO) const; 412 413+ unsigned getCallTargetOpValue(const MachineInstr &MI, 414+ unsigned) const; 415+ unsigned getBranchTargetOpValue(const MachineInstr &MI, 416+ unsigned) const; 417+ 418 void emitWord(unsigned Word); 419 420 unsigned getRelocation(const MachineInstr &MI, 421@@ -181,6 +186,18 @@ unsigned SparcCodeEmitter::getMachineOpValue(const 422 llvm_unreachable("Unable to encode MachineOperand!"); 423 return 0; 424 } 425+unsigned SparcCodeEmitter::getCallTargetOpValue(const MachineInstr &MI, 426+ unsigned opIdx) const { 427+ const MachineOperand MO = MI.getOperand(opIdx); 428+ return getMachineOpValue(MI, MO); 429+} 430+ 431+unsigned SparcCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI, 432+ unsigned opIdx) const { 433+ const MachineOperand MO = MI.getOperand(opIdx); 434+ return getMachineOpValue(MI, MO); 435+} 436+ 437 unsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI, 438 const MachineOperand &MO) const { 439 440Index: test/MC/Sparc/sparc-alu-instructions.s 441=================================================================== 442--- test/MC/Sparc/sparc-alu-instructions.s 443+++ test/MC/Sparc/sparc-alu-instructions.s 444@@ -0,0 +1,72 @@ 445+! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s 446+! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s 447+ 448+ ! CHECK: add %g0, %g0, %g0 ! encoding: [0x80,0x00,0x00,0x00] 449+ add %g0, %g0, %g0 450+ ! CHECK: add %g1, %g2, %g3 ! encoding: [0x86,0x00,0x40,0x02] 451+ add %g1, %g2, %g3 452+ ! CHECK: add %o0, %o1, %l0 ! encoding: [0xa0,0x02,0x00,0x09] 453+ add %r8, %r9, %l0 454+ ! CHECK: add %o0, 10, %l0 ! encoding: [0xa0,0x02,0x20,0x0a] 455+ add %o0, 10, %l0 456+ 457+ ! CHECK: addcc %g1, %g2, %g3 ! encoding: [0x86,0x80,0x40,0x02] 458+ addcc %g1, %g2, %g3 459+ 460+ ! CHECK: addxcc %g1, %g2, %g3 ! encoding: [0x86,0xc0,0x40,0x02] 461+ addxcc %g1, %g2, %g3 462+ 463+ ! CHECK: udiv %g1, %g2, %g3 ! encoding: [0x86,0x70,0x40,0x02] 464+ udiv %g1, %g2, %g3 465+ 466+ ! CHECK: sdiv %g1, %g2, %g3 ! encoding: [0x86,0x78,0x40,0x02] 467+ sdiv %g1, %g2, %g3 468+ 469+ ! CHECK: and %g1, %g2, %g3 ! encoding: [0x86,0x08,0x40,0x02] 470+ and %g1, %g2, %g3 471+ ! CHECK: andn %g1, %g2, %g3 ! encoding: [0x86,0x28,0x40,0x02] 472+ andn %g1, %g2, %g3 473+ ! CHECK: or %g1, %g2, %g3 ! encoding: [0x86,0x10,0x40,0x02] 474+ or %g1, %g2, %g3 475+ ! CHECK: orn %g1, %g2, %g3 ! encoding: [0x86,0x30,0x40,0x02] 476+ orn %g1, %g2, %g3 477+ ! CHECK: xor %g1, %g2, %g3 ! encoding: [0x86,0x18,0x40,0x02] 478+ xor %g1, %g2, %g3 479+ ! CHECK: xnor %g1, %g2, %g3 ! encoding: [0x86,0x38,0x40,0x02] 480+ xnor %g1, %g2, %g3 481+ 482+ ! CHECK: umul %g1, %g2, %g3 ! encoding: [0x86,0x50,0x40,0x02] 483+ umul %g1, %g2, %g3 484+ 485+ ! CHECK: smul %g1, %g2, %g3 ! encoding: [0x86,0x58,0x40,0x02] 486+ smul %g1, %g2, %g3 487+ 488+ ! CHECK: nop ! encoding: [0x01,0x00,0x00,0x00] 489+ nop 490+ 491+ ! CHECK: sethi 10, %l0 ! encoding: [0x21,0x00,0x00,0x0a] 492+ sethi 10, %l0 493+ 494+ ! CHECK: sll %g1, %g2, %g3 ! encoding: [0x87,0x28,0x40,0x02] 495+ sll %g1, %g2, %g3 496+ ! CHECK: sll %g1, 31, %g3 ! encoding: [0x87,0x28,0x60,0x1f] 497+ sll %g1, 31, %g3 498+ 499+ ! CHECK: srl %g1, %g2, %g3 ! encoding: [0x87,0x30,0x40,0x02] 500+ srl %g1, %g2, %g3 501+ ! CHECK: srl %g1, 31, %g3 ! encoding: [0x87,0x30,0x60,0x1f] 502+ srl %g1, 31, %g3 503+ 504+ ! CHECK: sra %g1, %g2, %g3 ! encoding: [0x87,0x38,0x40,0x02] 505+ sra %g1, %g2, %g3 506+ ! CHECK: sra %g1, 31, %g3 ! encoding: [0x87,0x38,0x60,0x1f] 507+ sra %g1, 31, %g3 508+ 509+ ! CHECK: sub %g1, %g2, %g3 ! encoding: [0x86,0x20,0x40,0x02] 510+ sub %g1, %g2, %g3 511+ ! CHECK: subcc %g1, %g2, %g3 ! encoding: [0x86,0xa0,0x40,0x02] 512+ subcc %g1, %g2, %g3 513+ 514+ ! CHECK: subxcc %g1, %g2, %g3 ! encoding: [0x86,0xe0,0x40,0x02] 515+ subxcc %g1, %g2, %g3 516+ 517