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.

llvm-svn: 119134
This commit is contained in:
Chris Lattner 2010-11-15 08:22:03 +00:00
parent 8f4444d003
commit efacb9ee42
5 changed files with 68 additions and 58 deletions

View File

@ -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"

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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();
}