Commit 1d0690bc by Jaydeep Patil Committed by Jim Stichnoth

[SubZero] Implement load and store for MIPS

This patch implements lowerLoad and extends existing lowerStore for byte, short and floating-point types. The patch also modifies PostLoweringLegalizer for conversion of mov to load or store. R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2301303003 . Patch from Jaydeep Patil <jaydeep.patil@imgtec.com>.
parent a0b720de
......@@ -649,10 +649,8 @@ void InstMIPS32Mov::dump(const Cfg *Func) const {
Str << ", ";
DestHi->dump(Func);
}
dumpOpcode(Str, " = mov", getDest()->getType());
Str << " ";
dumpSources(Func);
}
......@@ -711,9 +709,7 @@ void InstMIPS32Mov::emitSingleDestSingleSource(const Cfg *Func) const {
const char *ActualOpcode = nullptr;
const bool DestIsReg = Dest->hasReg();
const bool DestIsMem = !Dest->hasReg();
const bool SrcIsReg = (SrcV && SrcV->hasReg());
const bool SrcIsMem = !(SrcV && SrcV->hasReg());
// reg to reg
if (DestIsReg && SrcIsReg) {
......@@ -729,8 +725,8 @@ void InstMIPS32Mov::emitSingleDestSingleSource(const Cfg *Func) const {
case IceType_i16:
case IceType_i32:
Str << "\t"
"move"
"\t";
<< "move"
<< "\t";
getDest()->emit(Func);
Str << ", ";
getSrc(0)->emit(Func);
......@@ -748,64 +744,7 @@ void InstMIPS32Mov::emitSingleDestSingleSource(const Cfg *Func) const {
return;
}
// reg to stack
if (DestIsMem && SrcIsReg) {
switch (Dest->getType()) {
case IceType_f32:
ActualOpcode = "swc1";
break;
case IceType_f64:
ActualOpcode = "sdc1";
break;
case IceType_i1:
case IceType_i8:
case IceType_i16:
case IceType_i32:
ActualOpcode = "sw";
break;
default:
UnimplementedError(getFlags());
return;
}
assert(ActualOpcode);
Str << "\t" << ActualOpcode << "\t";
getSrc(0)->emit(Func);
Str << ", ";
getDest()->emit(Func);
return;
}
// stack to reg
if (DestIsReg && SrcIsMem) {
switch (Dest->getType()) {
case IceType_f32:
ActualOpcode = "lwc1";
break;
case IceType_f64:
ActualOpcode = "ldc1";
break;
case IceType_i1:
case IceType_i8:
case IceType_i16:
case IceType_i32:
ActualOpcode = "lw";
break;
default:
UnimplementedError(getFlags());
return;
}
assert(ActualOpcode);
Str << "\t" << ActualOpcode << "\t";
getDest()->emit(Func);
Str << ", ";
getSrc(0)->emit(Func);
return;
}
// stack to stack
llvm::report_fatal_error("mov cant copy stack to stack.");
llvm::report_fatal_error("Invalid mov instruction. Dest or Src is memory.");
}
template <> void InstMIPS32Addiu::emitIAS(const Cfg *Func) const {
......
......@@ -110,8 +110,21 @@ public:
static bool canHoldOffset(Type Ty, bool SignExt, int32_t Offset);
void dump(const Cfg *Func, Ostream &Str) const override {
(void)Func;
(void)Str;
if (!BuildDefs::dump())
return;
Str << "[";
if (Func)
getBase()->dump(Func);
else
getBase()->dump(Str);
Str << ", ";
getOffset()->dump(Func, Str);
Str << "] AddrMode==";
if (getAddrMode() == Offset) {
Str << "Offset";
} else {
Str << "Unknown";
}
}
private:
......@@ -515,8 +528,37 @@ public:
if (!BuildDefs::dump())
return;
Ostream &Str = Func->getContext()->getStrEmit();
assert(getSrcSize() == 1);
Str << "\t" << Opcode << "\t";
const Type Ty = getDest()->getType();
switch (Ty) {
case IceType_i1:
case IceType_i8:
Str << "\t"
<< "lb"
<< "\t";
break;
case IceType_i16:
Str << "\t"
<< "lh"
<< "\t";
break;
case IceType_i32:
Str << "\t"
<< "lw"
<< "\t";
break;
case IceType_f32:
Str << "\t"
<< "lwc1"
<< "\t";
break;
case IceType_f64:
Str << "\t"
<< "ldc1"
<< "\t";
break;
default:
llvm_unreachable("InstMIPS32Load unknown type");
}
getDest()->emit(Func);
Str << ", ";
emitRelocOp(Str, Reloc);
......@@ -532,13 +574,12 @@ public:
if (!BuildDefs::dump())
return;
Ostream &Str = Func->getContext()->getStrDump();
Str << "\t" << Opcode << "\t";
dumpOpcode(Str, Opcode, getDest()->getType());
Str << " ";
getDest()->dump(Func);
Str << ", ";
emitRelocOp(Str, Reloc);
Str << (Reloc ? "(" : "");
getSrc(0)->dump(Func);
Str << (Reloc ? ")" : "");
}
static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
......@@ -572,7 +613,37 @@ public:
return;
Ostream &Str = Func->getContext()->getStrEmit();
assert(getSrcSize() == 2);
Str << "\t" << Opcode << "\t";
const Type Ty = getSrc(0)->getType();
switch (Ty) {
case IceType_i1:
case IceType_i8:
Str << "\t"
<< "sb"
<< "\t";
break;
case IceType_i16:
Str << "\t"
<< "sh"
<< "\t";
break;
case IceType_i32:
Str << "\t"
<< "sw"
<< "\t";
break;
case IceType_f32:
Str << "\t"
<< "swc1"
<< "\t";
break;
case IceType_f64:
Str << "\t"
<< "sdc1"
<< "\t";
break;
default:
llvm_unreachable("InstMIPS32Store unknown type");
}
getSrc(0)->emit(Func);
Str << ", ";
emitRelocOp(Str, Reloc);
......@@ -581,20 +652,19 @@ public:
void emitIAS(const Cfg *Func) const override {
(void)Func;
llvm_unreachable("Not yet implemented");
llvm_unreachable("InstMIPS32Store: Not yet implemented");
}
void dump(const Cfg *Func) const override {
if (!BuildDefs::dump())
return;
Ostream &Str = Func->getContext()->getStrDump();
Str << "\t" << Opcode << "\t";
dumpOpcode(Str, Opcode, getSrc(0)->getType());
Str << " ";
getSrc(0)->dump(Func);
Str << ", ";
emitRelocOp(Str, Reloc);
Str << (Reloc ? "(" : "");
getSrc(1)->dump(Func);
Str << (Reloc ? ")" : "");
}
static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
......@@ -775,11 +845,12 @@ public:
if (!BuildDefs::dump())
return;
Ostream &Str = Func->getContext()->getStrDump();
dumpOpcode(Str, Opcode, getDest()->getType());
Str << " ";
Str << "\t" << Opcode << "\t";
dumpDest(Func);
Str << ", ";
dumpSources(Func);
Str << ", ";
if (Signed)
Str << (int32_t)Imm;
else
......
......@@ -101,9 +101,7 @@ public:
PrologEmitsFixedAllocas = true;
}
int32_t getFrameFixedAllocaOffset() const override {
// TODO(sehr): Implement fixed stack layout.
llvm::report_fatal_error("Not yet implemented");
return 0;
return FixedAllocaSizeBytes - (SpillAreaSizeBytes - MaxOutArgsSizeBytes);
}
uint32_t maxOutArgsSizeBytes() const override { return MaxOutArgsSizeBytes; }
......@@ -448,6 +446,7 @@ public:
Legal_Reg = 1 << 0, // physical register, not stack location
Legal_Imm = 1 << 1,
Legal_Mem = 1 << 2,
Legal_Rematerializable = 1 << 3,
Legal_Default = ~Legal_None
};
typedef uint32_t LegalMask;
......
......@@ -6,6 +6,13 @@
; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 | FileCheck %s
; RUN: %p2i --filetype=obj --disassemble -i %s --args -Om1 | FileCheck %s
; RUN: %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target mips32 -i %s --args -Om1 --skip-unimplemented \
; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix MIPS32 %s
define internal float @loadFloat(i32 %a) {
entry:
%__1 = inttoptr i32 %a to float*
......@@ -16,6 +23,9 @@ entry:
; CHECK: movss
; CHECK: fld
; MIPS32-LABEL: loadFloat
; MIPS32: lwc1 $f{{.*}},0{{.*}}
define internal double @loadDouble(i32 %a) {
entry:
%__1 = inttoptr i32 %a to double*
......@@ -26,6 +36,9 @@ entry:
; CHECK: movsd
; CHECK: fld
; MIPS32-LABEL: loadDouble
; MIPS32: ldc1 $f{{.*}},0{{.*}}
define internal void @storeFloat(i32 %a, float %value) {
entry:
%__2 = inttoptr i32 %a to float*
......@@ -36,6 +49,9 @@ entry:
; CHECK: movss
; CHECK: movss
; MIPS32-LABEL: storeFloat
; MIPS32: swc1 $f{{.*}},0{{.*}}
define internal void @storeDouble(i32 %a, double %value) {
entry:
%__2 = inttoptr i32 %a to double*
......@@ -46,6 +62,10 @@ entry:
; CHECK: movsd
; CHECK: movsd
; MIPS32-LABEL: storeDouble
; MIPS32: ldc1 $f{{.*}},4{{.*}}
; MIPS32: sdc1 $f{{.*}},0{{.*}}
define internal void @storeFloatConst(i32 %a) {
entry:
%a.asptr = inttoptr i32 %a to float*
......@@ -56,6 +76,11 @@ entry:
; CHECK: movss
; CHECK: movss
; MIPS32-LABEL: storeFloatConst
; MIPS32: lui {{.*}},{{.*}}
; MIPS32: lwc1 $f{{.*}},{{.*}}
; MIPS32: swc1 $f{{.*}},0{{.*}}
define internal void @storeDoubleConst(i32 %a) {
entry:
%a.asptr = inttoptr i32 %a to double*
......@@ -65,3 +90,8 @@ entry:
; CHECK-LABEL: storeDoubleConst
; CHECK: movsd
; CHECK: movsd
; MIPS32-LABEL: storeDoubleConst
; MIPS32: lui {{.*}},{{.*}}
; MIPS32: ldc1 $f{{.*}},{{.*}}
; MIPS32: sdc1 $f{{.*}},0{{.*}}
......@@ -4,6 +4,13 @@
; RUN: %p2i -i %s --args --verbose inst -threads=0 | FileCheck %s
; RUN: %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target mips32 -i %s --args -Om1 --skip-unimplemented \
; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix MIPS32 %s
define internal void @load_i64(i32 %addr_arg) {
entry:
%__1 = inttoptr i32 %addr_arg to i64*
......@@ -16,6 +23,10 @@ entry:
; CHECK-NEXT: ret void
}
; MIPS32-LABEL: load_i64
; MIPS32: lw {{.*}},0({{.*}})
; MIPS32-NEXT: lw {{.*}},4({{.*}})
define internal void @load_i32(i32 %addr_arg) {
entry:
%__1 = inttoptr i32 %addr_arg to i32*
......@@ -28,6 +39,9 @@ entry:
; CHECK-NEXT: ret void
}
; MIPS32-LABEL: load_i32
; MIPS32: lw {{.*}},0({{.*}})
define internal void @load_i16(i32 %addr_arg) {
entry:
%__1 = inttoptr i32 %addr_arg to i16*
......@@ -40,6 +54,9 @@ entry:
; CHECK-NEXT: ret void
}
; MIPS32-LABEL: load_i16
; MIPS32: lh {{.*}},0({{.*}})
define internal void @load_i8(i32 %addr_arg) {
entry:
%__1 = inttoptr i32 %addr_arg to i8*
......@@ -51,3 +68,6 @@ entry:
; CHECK-NEXT: %iv = load i8, i8* %addr_arg, align 1
; CHECK-NEXT: ret void
}
; MIPS32-LABEL: load_i8
; MIPS32: lb {{.*}},0({{.*}})
......@@ -56,7 +56,7 @@ entry:
}
; MIPS32-LABEL: store_i16
; MIPS32: li
; MIPS32: sw
; MIPS32: sh
define internal void @store_i8(i32 %addr_arg) {
entry:
......@@ -71,4 +71,34 @@ entry:
}
; MIPS32-LABEL: store_i8
; MIPS32: li
; MIPS32: sw
\ No newline at end of file
; MIPS32: sb
define internal void @store_f32(float* %faddr_arg) {
entry:
store float 1.000000e+00, float* %faddr_arg, align 4
ret void
; CHECK: Initial CFG
; CHECK: entry:
; CHECK-NEXT: store float 1.000000e+00, float* %faddr_arg, align 4
; CHECK-NEXT: ret void
}
; MIPS32-LABEL: store_f32
; MIPS32: lui
; MIPS32: lwc1
; MIPS32: swc1
define internal void @store_f64(double* %daddr_arg) {
entry:
store double 1.000000e+00, double* %daddr_arg, align 8
ret void
; CHECK: Initial CFG
; CHECK: entry:
; CHECK-NEXT: store double 1.000000e+00, double* %daddr_arg, align 8
; CHECK-NEXT: ret void
}
; MIPS32-LABEL: store_f64
; MIPS32: lui
; MIPS32: ldc1
; MIPS32: sdc1
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