forked from OSchip/llvm-project
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:
parent
8f4444d003
commit
efacb9ee42
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue