Commit 45e4d5ed by Jaydeep Patil Committed by Jim Stichnoth

[SubZero] Handle relocatable constants for MIPS

The patch generates HI/LO modifiers for relocatable constants. R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2420033002 . Patch from Jaydeep Patil <jaydeep.patil@imgtec.com>.
parent 46832371
......@@ -983,14 +983,21 @@ class InstMIPS32Imm16 : public InstMIPS32 {
public:
static InstMIPS32Imm16 *create(Cfg *Func, Variable *Dest, Operand *Source,
uint32_t Imm) {
uint32_t Imm, RelocOp Reloc = RO_No) {
return new (Func->allocate<InstMIPS32Imm16>())
InstMIPS32Imm16(Func, Dest, Source, Imm);
InstMIPS32Imm16(Func, Dest, Source, Imm, Reloc);
}
static InstMIPS32Imm16 *create(Cfg *Func, Variable *Dest, uint32_t Imm) {
static InstMIPS32Imm16 *create(Cfg *Func, Variable *Dest, uint32_t Imm,
RelocOp Reloc = RO_No) {
return new (Func->allocate<InstMIPS32Imm16>())
InstMIPS32Imm16(Func, Dest, Imm);
InstMIPS32Imm16(Func, Dest, Imm, Reloc);
}
static InstMIPS32Imm16 *create(Cfg *Func, Variable *Dest, Operand *Src0,
Operand *Src1, RelocOp Reloc) {
return new (Func->allocate<InstMIPS32Imm16>())
InstMIPS32Imm16(Func, Dest, Src0, Src1, Reloc);
}
void emit(const Cfg *Func) const override {
......@@ -1004,10 +1011,18 @@ public:
getSrc(0)->emit(Func);
}
Str << ", ";
if (Signed)
Str << (int32_t)Imm;
else
Str << Imm;
if (Reloc == RO_No) {
if (Signed)
Str << (int32_t)Imm;
else
Str << Imm;
} else {
auto *CR = llvm::dyn_cast<ConstantRelocatable>(getSrc(1));
emitRelocOp(Str, Reloc);
Str << "(";
CR->emitWithoutPrefix(Func->getTarget());
Str << ")";
}
}
void emitIAS(const Cfg *Func) const override {
......@@ -1022,27 +1037,45 @@ public:
Str << " ";
dumpDest(Func);
Str << ", ";
dumpSources(Func);
Str << ", ";
if (Signed)
Str << (int32_t)Imm;
else
Str << Imm;
if (Reloc == RO_No) {
dumpSources(Func);
Str << ", ";
if (Signed)
Str << (int32_t)Imm;
else
Str << Imm;
} else {
getSrc(0)->dump(Func);
Str << ",";
emitRelocOp(Str, Reloc);
Str << "(";
getSrc(1)->dump(Func);
Str << ")";
}
}
static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
private:
InstMIPS32Imm16(Cfg *Func, Variable *Dest, Operand *Source, uint32_t Imm)
: InstMIPS32(Func, K, 1, Dest), Imm(Imm) {
InstMIPS32Imm16(Cfg *Func, Variable *Dest, Operand *Source, uint32_t Imm,
RelocOp Reloc = RO_No)
: InstMIPS32(Func, K, 1, Dest), Reloc(Reloc), Imm(Imm) {
addSource(Source);
}
InstMIPS32Imm16(Cfg *Func, Variable *Dest, uint32_t Imm)
: InstMIPS32(Func, K, 0, Dest), Imm(Imm) {}
InstMIPS32Imm16(Cfg *Func, Variable *Dest, uint32_t Imm,
RelocOp Reloc = RO_No)
: InstMIPS32(Func, K, 0, Dest), Reloc(Reloc), Imm(Imm) {}
static const char *Opcode;
InstMIPS32Imm16(Cfg *Func, Variable *Dest, Operand *Src0, Operand *Src1,
RelocOp Reloc = RO_No)
: InstMIPS32(Func, K, 1, Dest), Reloc(Reloc), Imm(0) {
addSource(Src0);
addSource(Src1);
}
static const char *Opcode;
const RelocOp Reloc;
const uint32_t Imm;
};
......
......@@ -4961,10 +4961,10 @@ Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed,
return From;
}
if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) {
(void)C;
// TODO(reed kotler): complete this case for proper implementation
Variable *Reg = makeReg(Ty, RegNum);
Context.insert<InstFakeDef>(Reg);
Variable *TReg = makeReg(Ty, RegNum);
_lui(TReg, C, RO_Hi);
_addiu(Reg, TReg, C, RO_Lo);
return Reg;
} else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) {
const uint32_t Value = C32->getValue();
......
......@@ -216,6 +216,10 @@ public:
Context.insert<InstMIPS32Addiu>(Dest, Src, Imm);
}
void _addiu(Variable *Dest, Variable *Src0, Operand *Src1, RelocOp Reloc) {
Context.insert<InstMIPS32Addiu>(Dest, Src0, Src1, Reloc);
}
void _c_eq_d(Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32C_eq_d>(Src0, Src1);
}
......
......@@ -276,6 +276,11 @@ entry:
; CHECK-LABEL: ShlReloc
; CHECK: shl {{.*}},cl
; MIPS32-LABEL: ShlReloc
; MIPS32: lui [[REG:.*]],{{.*}} R_MIPS_HI16 G
; MIPS32: addiu [[REG]],[[REG]],{{.*}} R_MIPS_LO16 G
; MIPS32: sllv {{.*}},{{.*}},[[REG]]
define internal i32 @LshrReloc(i32 %a) {
entry:
%opnd = ptrtoint [4 x i8]* @G to i32
......@@ -285,6 +290,11 @@ entry:
; CHECK-LABEL: LshrReloc
; CHECK: shr {{.*}},cl
; MIPS32-LABEL: LshrReloc
; MIPS32: lui [[REG:.*]],{{.*}} R_MIPS_HI16 G
; MIPS32: addiu [[REG]],[[REG]],{{.*}} R_MIPS_LO16 G
; MIPS32: srlv {{.*}},{{.*}},[[REG]]
define internal i32 @AshrReloc(i32 %a) {
entry:
%opnd = ptrtoint [4 x i8]* @G to i32
......@@ -293,3 +303,8 @@ entry:
}
; CHECK-LABEL: AshrReloc
; CHECK: sar {{.*}},cl
; MIPS32-LABEL: AshrReloc
; MIPS32: lui [[REG:.*]],{{.*}} R_MIPS_HI16 G
; MIPS32: addiu [[REG]],[[REG]],{{.*}} R_MIPS_LO16 G
; MIPS32: srav {{.*}},{{.*}},[[REG]]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment