diff options
author | Chris Lattner <sabre@nondot.org> | 2010-11-15 08:22:03 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-11-15 08:22:03 +0000 |
commit | b7035d04421112a4585245f67bc564170ec45b29 (patch) | |
tree | ff86ab219c3c14c38b6b39f42e73d545d30f0ca0 /lib | |
parent | 17e2c188359769a1df18c42593a94ce0fc2a9a75 (diff) | |
download | external_llvm-b7035d04421112a4585245f67bc564170ec45b29.zip external_llvm-b7035d04421112a4585245f67bc564170ec45b29.tar.gz external_llvm-b7035d04421112a4585245f67bc564170ec45b29.tar.bz2 |
split out an encoder for memri operands, allowing a relocation to be plopped
into the immediate field. This allows us to encode stuff like this:
lbz r3, lo16(__ZL4init)(r4) ; globalopt.cpp:5
; encoding: [0x88,0x64,A,A]
; fixup A - offset: 0, value: lo16(__ZL4init), kind: fixup_ppc_lo16
stw r3, lo16(__ZL1s)(r5) ; globalopt.cpp:6
; encoding: [0x90,0x65,A,A]
; fixup A - offset: 0, value: lo16(__ZL1s), kind: fixup_ppc_lo16
With this, we should have a completely function MCCodeEmitter for PPC, wewt.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119134 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/PowerPC/PPCCodeEmitter.cpp | 63 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstr64Bit.td | 6 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstrFormats.td | 17 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.td | 11 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCMCCodeEmitter.cpp | 29 |
5 files changed, 68 insertions, 58 deletions
diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index 48848e3..4633215 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -66,6 +66,7 @@ namespace { unsigned getHA16Encoding(const MachineInstr &MI, unsigned OpNo) const; unsigned getLO16Encoding(const MachineInstr &MI, unsigned OpNo) const; + unsigned getMemRIEncoding(const MachineInstr &MI, unsigned OpNo) const; unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const; const char *getPassName() const { return "PowerPC Machine Code Emitter"; } @@ -209,6 +210,22 @@ unsigned PPCCodeEmitter::getLO16Encoding(const MachineInstr &MI, return 0; } +unsigned PPCCodeEmitter::getMemRIEncoding(const MachineInstr &MI, + unsigned OpNo) const { + // Encode (imm, reg) as a memri, which has the low 16-bits as the + // displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 16; + + const MachineOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) + return (getMachineOpValue(MI, MO) & 0xFFFF) | RegBits; + + // Add a fixup for the displacement field. + MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low)); + return RegBits; +} + unsigned PPCCodeEmitter::getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const { // Encode (imm, reg) as a memrix, which has the low 14-bits as the @@ -233,49 +250,9 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, return PPCRegisterInfo::getRegisterNumbering(MO.getReg()); } - if (MO.isImm()) - return MO.getImm(); - - if (MO.isGlobal() || MO.isSymbol() || MO.isCPI() || MO.isJTI()) { - unsigned Reloc = 0; - assert((TM.getRelocationModel() != Reloc::PIC_ || MovePCtoLROffset) && - "MovePCtoLR not seen yet?"); - switch (MI.getOpcode()) { - default: MI.dump(); llvm_unreachable("Unknown instruction for relocation!"); - // Loads. - case PPC::LBZ: - case PPC::LBZ8: - case PPC::LHA: - case PPC::LHA8: - case PPC::LHZ: - case PPC::LHZ8: - case PPC::LWZ: - case PPC::LWZ8: - case PPC::LFS: - case PPC::LFD: - - // Stores. - case PPC::STB: - case PPC::STB8: - case PPC::STH: - case PPC::STH8: - case PPC::STW: - case PPC::STW8: - case PPC::STFS: - case PPC::STFD: - Reloc = PPC::reloc_absolute_low; - break; - } - - MCE.addRelocation(GetRelocation(MO, Reloc)); - } else { -#ifndef NDEBUG - errs() << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; -#endif - llvm_unreachable(0); - } - - return 0; + assert(MO.isImm() && + "Relocation required in an instruction that we cannot encode!"); + return MO.getImm(); } #include "PPCGenCodeEmitter.inc" diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index fada63d..6636b69 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -493,7 +493,7 @@ def LWAX : XForm_1<31, 341, (outs G8RC:$rD), (ins memrr:$src), // Update forms. let mayLoad = 1 in -def LHAU8 : DForm_1<43, (outs G8RC:$rD, ptr_rc:$ea_result), (ins symbolLo:$disp, +def LHAU8 : DForm_1a<43, (outs G8RC:$rD, ptr_rc:$ea_result), (ins symbolLo:$disp, ptr_rc:$rA), "lhau $rD, $disp($rA)", LdStGeneral, []>, RegConstraint<"$rA = $ea_result">, @@ -614,14 +614,14 @@ def STDX : XForm_8<31, 149, (outs), (ins G8RC:$rS, memrr:$dst), let PPC970_Unit = 2 in { -def STBU8 : DForm_1<38, (outs ptr_rc:$ea_res), (ins G8RC:$rS, +def STBU8 : DForm_1a<38, (outs ptr_rc:$ea_res), (ins G8RC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "stbu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, (pre_truncsti8 G8RC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff))]>, RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; -def STHU8 : DForm_1<45, (outs ptr_rc:$ea_res), (ins G8RC:$rS, +def STHU8 : DForm_1a<45, (outs ptr_rc:$ea_res), (ins G8RC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "sthu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, diff --git a/lib/Target/PowerPC/PPCInstrFormats.td b/lib/Target/PowerPC/PPCInstrFormats.td index 3949bd3..84a15b1 100644 --- a/lib/Target/PowerPC/PPCInstrFormats.td +++ b/lib/Target/PowerPC/PPCInstrFormats.td @@ -102,6 +102,19 @@ class DForm_1<bits<6> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : I<opcode, OOL, IOL, asmstr, itin> { bits<5> A; + bits<21> Addr; + + let Pattern = pattern; + + let Inst{6-10} = A; + let Inst{11-15} = Addr{20-16}; // Base Reg + let Inst{16-31} = Addr{15-0}; // Displacement +} + +class DForm_1a<bits<6> opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list<dag> pattern> + : I<opcode, OOL, IOL, asmstr, itin> { + bits<5> A; bits<16> C; bits<5> B; @@ -112,6 +125,7 @@ class DForm_1<bits<6> opcode, dag OOL, dag IOL, string asmstr, let Inst{16-31} = C; } + class DForm_2<bits<6> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : DForm_base<opcode, OOL, IOL, asmstr, itin, pattern>; @@ -147,8 +161,7 @@ class DForm_4_zero<bits<6> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : DForm_1<opcode, OOL, IOL, asmstr, itin, pattern> { let A = 0; - let B = 0; - let C = 0; + let Addr = 0; } class DForm_5<bits<6> opcode, dag OOL, dag IOL, string asmstr, diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index a9b1d87..9abf92c 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -316,6 +316,7 @@ def crbitm: Operand<i8> { def memri : Operand<iPTR> { let PrintMethod = "printMemRegImm"; let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg); + let EncoderMethod = "getMemRIEncoding"; } def memrr : Operand<iPTR> { let PrintMethod = "printMemRegReg"; @@ -763,33 +764,33 @@ def STFD : DForm_1<54, (outs), (ins F8RC:$rS, memri:$dst), // Unindexed (r+i) Stores with Update (preinc). let PPC970_Unit = 2 in { -def STBU : DForm_1<39, (outs ptr_rc:$ea_res), (ins GPRC:$rS, +def STBU : DForm_1a<39, (outs ptr_rc:$ea_res), (ins GPRC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "stbu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, (pre_truncsti8 GPRC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff))]>, RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; -def STHU : DForm_1<45, (outs ptr_rc:$ea_res), (ins GPRC:$rS, +def STHU : DForm_1a<45, (outs ptr_rc:$ea_res), (ins GPRC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "sthu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, (pre_truncsti16 GPRC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff))]>, RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; -def STWU : DForm_1<37, (outs ptr_rc:$ea_res), (ins GPRC:$rS, +def STWU : DForm_1a<37, (outs ptr_rc:$ea_res), (ins GPRC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "stwu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, (pre_store GPRC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff))]>, RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; -def STFSU : DForm_1<37, (outs ptr_rc:$ea_res), (ins F4RC:$rS, +def STFSU : DForm_1a<37, (outs ptr_rc:$ea_res), (ins F4RC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "stfsu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, (pre_store F4RC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff))]>, RegConstraint<"$ptrreg = $ea_res">, NoEncode<"$ea_res">; -def STFDU : DForm_1<37, (outs ptr_rc:$ea_res), (ins F8RC:$rS, +def STFDU : DForm_1a<37, (outs ptr_rc:$ea_res), (ins F8RC:$rS, symbolLo:$ptroff, ptr_rc:$ptrreg), "stfdu $rS, $ptroff($ptrreg)", LdStGeneral, [(set ptr_rc:$ea_res, (pre_store F8RC:$rS, ptr_rc:$ptrreg, diff --git a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp index 66c0bb7..ea5275a 100644 --- a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp @@ -66,6 +66,8 @@ public: SmallVectorImpl<MCFixup> &Fixups) const; unsigned getLO16Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) const; + unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups) const; unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) const; unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo, @@ -147,10 +149,29 @@ unsigned PPCMCCodeEmitter::getLO16Encoding(const MCInst &MI, unsigned OpNo, return 0; } +unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups) const { + // Encode (imm, reg) as a memri, which has the low 16-bits as the + // displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups) << 16; + + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) + return (getMachineOpValue(MI, MO, Fixups) & 0xFFFF) | RegBits; + + // Add a fixup for the displacement field. + Fixups.push_back(MCFixup::Create(0, MO.getExpr(), + (MCFixupKind)PPC::fixup_ppc_lo16)); + return RegBits; +} + + unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) const { // Encode (imm, reg) as a memrix, which has the low 14-bits as the // displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups) << 14; const MCOperand &MO = MI.getOperand(OpNo); @@ -182,11 +203,9 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO, return PPCRegisterInfo::getRegisterNumbering(MO.getReg()); } - if (MO.isImm()) - return MO.getImm(); - - // FIXME. - return 0; + assert(MO.isImm() && + "Relocation required in an instruction that we cannot encode!"); + return MO.getImm(); } |