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 { ...@@ -983,14 +983,21 @@ class InstMIPS32Imm16 : public InstMIPS32 {
public: public:
static InstMIPS32Imm16 *create(Cfg *Func, Variable *Dest, Operand *Source, static InstMIPS32Imm16 *create(Cfg *Func, Variable *Dest, Operand *Source,
uint32_t Imm) { uint32_t Imm, RelocOp Reloc = RO_No) {
return new (Func->allocate<InstMIPS32Imm16>()) 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, Reloc);
}
static InstMIPS32Imm16 *create(Cfg *Func, Variable *Dest, Operand *Src0,
Operand *Src1, RelocOp Reloc) {
return new (Func->allocate<InstMIPS32Imm16>()) return new (Func->allocate<InstMIPS32Imm16>())
InstMIPS32Imm16(Func, Dest, Imm); InstMIPS32Imm16(Func, Dest, Src0, Src1, Reloc);
} }
void emit(const Cfg *Func) const override { void emit(const Cfg *Func) const override {
...@@ -1004,10 +1011,18 @@ public: ...@@ -1004,10 +1011,18 @@ public:
getSrc(0)->emit(Func); getSrc(0)->emit(Func);
} }
Str << ", "; Str << ", ";
if (Reloc == RO_No) {
if (Signed) if (Signed)
Str << (int32_t)Imm; Str << (int32_t)Imm;
else else
Str << Imm; 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 { void emitIAS(const Cfg *Func) const override {
...@@ -1022,27 +1037,45 @@ public: ...@@ -1022,27 +1037,45 @@ public:
Str << " "; Str << " ";
dumpDest(Func); dumpDest(Func);
Str << ", "; Str << ", ";
if (Reloc == RO_No) {
dumpSources(Func); dumpSources(Func);
Str << ", "; Str << ", ";
if (Signed) if (Signed)
Str << (int32_t)Imm; Str << (int32_t)Imm;
else else
Str << Imm; 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); } static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
private: private:
InstMIPS32Imm16(Cfg *Func, Variable *Dest, Operand *Source, uint32_t Imm) InstMIPS32Imm16(Cfg *Func, Variable *Dest, Operand *Source, uint32_t Imm,
: InstMIPS32(Func, K, 1, Dest), Imm(Imm) { RelocOp Reloc = RO_No)
: InstMIPS32(Func, K, 1, Dest), Reloc(Reloc), Imm(Imm) {
addSource(Source); addSource(Source);
} }
InstMIPS32Imm16(Cfg *Func, Variable *Dest, uint32_t Imm) InstMIPS32Imm16(Cfg *Func, Variable *Dest, uint32_t Imm,
: InstMIPS32(Func, K, 0, Dest), Imm(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; const uint32_t Imm;
}; };
......
...@@ -4961,10 +4961,10 @@ Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, ...@@ -4961,10 +4961,10 @@ Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed,
return From; return From;
} }
if (auto *C = llvm::dyn_cast<ConstantRelocatable>(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); 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; return Reg;
} else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) {
const uint32_t Value = C32->getValue(); const uint32_t Value = C32->getValue();
......
...@@ -216,6 +216,10 @@ public: ...@@ -216,6 +216,10 @@ public:
Context.insert<InstMIPS32Addiu>(Dest, Src, Imm); 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) { void _c_eq_d(Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32C_eq_d>(Src0, Src1); Context.insert<InstMIPS32C_eq_d>(Src0, Src1);
} }
......
...@@ -276,6 +276,11 @@ entry: ...@@ -276,6 +276,11 @@ entry:
; CHECK-LABEL: ShlReloc ; CHECK-LABEL: ShlReloc
; CHECK: shl {{.*}},cl ; 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) { define internal i32 @LshrReloc(i32 %a) {
entry: entry:
%opnd = ptrtoint [4 x i8]* @G to i32 %opnd = ptrtoint [4 x i8]* @G to i32
...@@ -285,6 +290,11 @@ entry: ...@@ -285,6 +290,11 @@ entry:
; CHECK-LABEL: LshrReloc ; CHECK-LABEL: LshrReloc
; CHECK: shr {{.*}},cl ; 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) { define internal i32 @AshrReloc(i32 %a) {
entry: entry:
%opnd = ptrtoint [4 x i8]* @G to i32 %opnd = ptrtoint [4 x i8]* @G to i32
...@@ -293,3 +303,8 @@ entry: ...@@ -293,3 +303,8 @@ entry:
} }
; CHECK-LABEL: AshrReloc ; CHECK-LABEL: AshrReloc
; CHECK: sar {{.*}},cl ; 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