Index: src/IceInstARM32.cpp |
diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp |
index 70b6791f0cece58decbf2121aa02619f169c2fe9..15664f7c1cf480a61b0a22a8e1b63befacf9c5a6 100644 |
--- a/src/IceInstARM32.cpp |
+++ b/src/IceInstARM32.cpp |
@@ -28,12 +28,13 @@ namespace Ice { |
namespace { |
const struct TypeARM32Attributes_ { |
- const char *WidthString; // b, h, <blank>, or d |
+ const char *WidthString; // b, h, <blank>, or d |
+ const char *VecWidthString; // i8, i16, i32, f32, f64 |
int8_t SExtAddrOffsetBits; |
int8_t ZExtAddrOffsetBits; |
} TypeARM32Attributes[] = { |
-#define X(tag, elementty, width, sbits, ubits) \ |
- { width, sbits, ubits } \ |
+#define X(tag, elementty, int_width, vec_width, sbits, ubits) \ |
+ { int_width, vec_width, sbits, ubits } \ |
, |
ICETYPEARM32_TABLE |
#undef X |
@@ -66,6 +67,10 @@ const char *InstARM32::getWidthString(Type Ty) { |
return TypeARM32Attributes[Ty].WidthString; |
} |
+const char *InstARM32::getVecWidthString(Type Ty) { |
+ return TypeARM32Attributes[Ty].VecWidthString; |
+} |
+ |
const char *InstARM32Pred::predString(CondARM32::Cond Pred) { |
return InstARM32CondAttributes[Pred].EmitString; |
} |
@@ -94,6 +99,18 @@ void InstARM32Pred::emitUnaryopGPR(const char *Opcode, |
Inst->getSrc(0)->emit(Func); |
} |
+void InstARM32Pred::emitUnaryopFP(const char *Opcode, const InstARM32Pred *Inst, |
+ const Cfg *Func) { |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ assert(Inst->getSrcSize() == 1); |
+ Type SrcTy = Inst->getSrc(0)->getType(); |
+ Str << "\t" << Opcode << Inst->getPredicate() << getVecWidthString(SrcTy) |
+ << "\t"; |
+ Inst->getDest()->emit(Func); |
+ Str << ", "; |
+ Inst->getSrc(0)->emit(Func); |
+} |
+ |
void InstARM32Pred::emitTwoAddr(const char *Opcode, const InstARM32Pred *Inst, |
const Cfg *Func) { |
if (!BuildDefs::dump()) |
@@ -123,6 +140,21 @@ void InstARM32Pred::emitThreeAddr(const char *Opcode, const InstARM32Pred *Inst, |
Inst->getSrc(1)->emit(Func); |
} |
+void InstARM32::emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst, |
+ const Cfg *Func) { |
+ if (!BuildDefs::dump()) |
+ return; |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ assert(Inst->getSrcSize() == 2); |
+ Str << "\t" << Opcode << getVecWidthString(Inst->getDest()->getType()) |
+ << "\t"; |
+ Inst->getDest()->emit(Func); |
+ Str << ", "; |
+ Inst->getSrc(0)->emit(Func); |
+ Str << ", "; |
+ Inst->getSrc(1)->emit(Func); |
+} |
+ |
void InstARM32Pred::emitFourAddr(const char *Opcode, const InstARM32Pred *Inst, |
const Cfg *Func) { |
if (!BuildDefs::dump()) |
@@ -304,12 +336,6 @@ IceString InstARM32Label::getName(const Cfg *Func) const { |
return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); |
} |
-InstARM32Ldr::InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, |
- CondARM32::Cond Predicate) |
- : InstARM32Pred(Func, InstARM32::Ldr, 1, Dest, Predicate) { |
- addSource(Mem); |
-} |
- |
InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) |
: InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { |
// Track modifications to Dests separately via FakeDefs. |
@@ -363,8 +389,14 @@ template <> const char *InstARM32Rbit::Opcode = "rbit"; |
template <> const char *InstARM32Rev::Opcode = "rev"; |
template <> const char *InstARM32Sxt::Opcode = "sxt"; // still requires b/h |
template <> const char *InstARM32Uxt::Opcode = "uxt"; // still requires b/h |
+// FP |
+template <> const char *InstARM32Vsqrt::Opcode = "vsqrt"; |
// Mov-like ops |
+template <> const char *InstARM32Ldr::Opcode = "ldr"; |
template <> const char *InstARM32Mov::Opcode = "mov"; |
+// FP |
+template <> const char *InstARM32Vldr::Opcode = "vldr"; |
+template <> const char *InstARM32Vmov::Opcode = "vmov"; |
// Three-addr ops |
template <> const char *InstARM32Adc::Opcode = "adc"; |
template <> const char *InstARM32Add::Opcode = "add"; |
@@ -381,6 +413,11 @@ template <> const char *InstARM32Sbc::Opcode = "sbc"; |
template <> const char *InstARM32Sdiv::Opcode = "sdiv"; |
template <> const char *InstARM32Sub::Opcode = "sub"; |
template <> const char *InstARM32Udiv::Opcode = "udiv"; |
+// FP |
+template <> const char *InstARM32Vadd::Opcode = "vadd"; |
+template <> const char *InstARM32Vdiv::Opcode = "vdiv"; |
+template <> const char *InstARM32Vmul::Opcode = "vmul"; |
+template <> const char *InstARM32Vsub::Opcode = "vsub"; |
// Four-addr ops |
template <> const char *InstARM32Mla::Opcode = "mla"; |
template <> const char *InstARM32Mls::Opcode = "mls"; |
@@ -403,19 +440,19 @@ template <> void InstARM32Mov::emit(const Cfg *Func) const { |
assert(getSrcSize() == 1); |
Variable *Dest = getDest(); |
if (Dest->hasReg()) { |
- IceString Opcode = "mov"; |
+ IceString ActualOpcode = Opcode; |
Operand *Src0 = getSrc(0); |
if (const auto *Src0V = llvm::dyn_cast<Variable>(Src0)) { |
if (!Src0V->hasReg()) { |
// Always use the whole stack slot. A 32-bit load has a larger range |
// of offsets than 16-bit, etc. |
- Opcode = IceString("ldr"); |
+ ActualOpcode = IceString("ldr"); |
} |
} else { |
if (llvm::isa<OperandARM32Mem>(Src0)) |
- Opcode = IceString("ldr") + getWidthString(Dest->getType()); |
+ ActualOpcode = IceString("ldr") + getWidthString(Dest->getType()); |
} |
- Str << "\t" << Opcode << getPredicate() << "\t"; |
+ Str << "\t" << ActualOpcode << getPredicate() << "\t"; |
getDest()->emit(Func); |
Str << ", "; |
getSrc(0)->emit(Func); |
@@ -436,6 +473,64 @@ template <> void InstARM32Mov::emitIAS(const Cfg *Func) const { |
llvm_unreachable("Not yet implemented"); |
} |
+template <> void InstARM32Vldr::emit(const Cfg *Func) const { |
+ if (!BuildDefs::dump()) |
+ return; |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ assert(getSrcSize() == 1); |
+ assert(getDest()->hasReg()); |
+ Str << "\t"<< Opcode << getPredicate() << "\t"; |
+ getDest()->emit(Func); |
+ Str << ", "; |
+ getSrc(0)->emit(Func); |
+} |
+ |
+template <> void InstARM32Vldr::emitIAS(const Cfg *Func) const { |
+ assert(getSrcSize() == 1); |
+ (void)Func; |
+ llvm_unreachable("Not yet implemented"); |
+} |
+ |
+template <> void InstARM32Vmov::emit(const Cfg *Func) const { |
+ if (!BuildDefs::dump()) |
+ return; |
+ assert(CondARM32::AL == getPredicate()); |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ assert(getSrcSize() == 1); |
+ Variable *Dest = getDest(); |
+ if (Dest->hasReg()) { |
+ IceString ActualOpcode = Opcode; |
+ Operand *Src0 = getSrc(0); |
+ if (const auto *Src0V = llvm::dyn_cast<Variable>(Src0)) { |
+ if (!Src0V->hasReg()) { |
+ ActualOpcode = IceString("vldr"); |
+ } |
+ } else { |
+ if (llvm::isa<OperandARM32Mem>(Src0)) |
+ ActualOpcode = IceString("vldr"); |
+ } |
+ Str << "\t" << ActualOpcode << "\t"; |
+ getDest()->emit(Func); |
+ Str << ", "; |
+ getSrc(0)->emit(Func); |
+ } else { |
+ Variable *Src0 = llvm::cast<Variable>(getSrc(0)); |
+ assert(Src0->hasReg()); |
+ Str << "\t" |
+ "vstr" |
+ "\t"; |
+ Src0->emit(Func); |
+ Str << ", "; |
+ Dest->emit(Func); |
+ } |
+} |
+ |
+template <> void InstARM32Vmov::emitIAS(const Cfg *Func) const { |
+ assert(getSrcSize() == 1); |
+ (void)Func; |
+ llvm_unreachable("Not yet implemented"); |
+} |
+ |
void InstARM32Br::emit(const Cfg *Func) const { |
if (!BuildDefs::dump()) |
return; |
@@ -547,37 +642,25 @@ void InstARM32Label::dump(const Cfg *Func) const { |
Str << getName(Func) << ":"; |
} |
-void InstARM32Ldr::emit(const Cfg *Func) const { |
+template <> void InstARM32Ldr::emit(const Cfg *Func) const { |
if (!BuildDefs::dump()) |
return; |
Ostream &Str = Func->getContext()->getStrEmit(); |
assert(getSrcSize() == 1); |
assert(getDest()->hasReg()); |
Type Ty = getSrc(0)->getType(); |
- Str << "\t" |
- << "ldr" << getWidthString(Ty) << getPredicate() << "\t"; |
+ Str << "\t"<< Opcode << getWidthString(Ty) << getPredicate() << "\t"; |
getDest()->emit(Func); |
Str << ", "; |
getSrc(0)->emit(Func); |
} |
-void InstARM32Ldr::emitIAS(const Cfg *Func) const { |
+template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const { |
assert(getSrcSize() == 1); |
(void)Func; |
llvm_unreachable("Not yet implemented"); |
} |
-void InstARM32Ldr::dump(const Cfg *Func) const { |
- if (!BuildDefs::dump()) |
- return; |
- Ostream &Str = Func->getContext()->getStrDump(); |
- dumpDest(Func); |
- Str << " = "; |
- dumpOpcodePred(Str, "ldr", getDest()->getType()); |
- Str << " "; |
- dumpSources(Func); |
-} |
- |
template <> void InstARM32Movw::emit(const Cfg *Func) const { |
if (!BuildDefs::dump()) |
return; |