Commit 080b65b5 by Karl Schimpf

Add MLA instruction to ARM integerated assembler.

parent 856734ca
...@@ -391,13 +391,15 @@ void Assembler::muls(Register rd, Register rn, Register rm, Condition cond) { ...@@ -391,13 +391,15 @@ void Assembler::muls(Register rd, Register rn, Register rm, Condition cond) {
EmitMulOp(cond, B20, R0, rd, rn, rm); EmitMulOp(cond, B20, R0, rd, rn, rm);
} }
#if 0
// Moved to ARM32::AssemblerARM32::mla
void Assembler::mla(Register rd, Register rn, void Assembler::mla(Register rd, Register rn,
Register rm, Register ra, Condition cond) { Register rm, Register ra, Condition cond) {
// rd <- ra + rn * rm. // rd <- ra + rn * rm.
// Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
EmitMulOp(cond, B21, ra, rd, rn, rm); EmitMulOp(cond, B21, ra, rd, rn, rm);
} }
#endif
void Assembler::mls(Register rd, Register rn, void Assembler::mls(Register rd, Register rn,
......
...@@ -521,9 +521,11 @@ class Assembler : public ValueObject { ...@@ -521,9 +521,11 @@ class Assembler : public ValueObject {
// Moved to ARM32::AssemblerARM32::mul() // Moved to ARM32::AssemblerARM32::mul()
void mul(Register rd, Register rn, Register rm, Condition cond = AL); void mul(Register rd, Register rn, Register rm, Condition cond = AL);
void muls(Register rd, Register rn, Register rm, Condition cond = AL); void muls(Register rd, Register rn, Register rm, Condition cond = AL);
#endif
// Moved to ARM32::AssemblerARM32::mla()
void mla(Register rd, Register rn, Register rm, Register ra, void mla(Register rd, Register rn, Register rm, Register ra,
Condition cond = AL); Condition cond = AL);
#endif
void mls(Register rd, Register rn, Register rm, Register ra, void mls(Register rd, Register rn, Register rm, Register ra,
Condition cond = AL); Condition cond = AL);
void smull(Register rd_lo, Register rd_hi, Register rn, Register rm, void smull(Register rd_lo, Register rd_hi, Register rn, Register rm,
......
...@@ -886,6 +886,35 @@ void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn, ...@@ -886,6 +886,35 @@ void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn,
emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond); emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond);
} }
void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn,
const Operand *OpRm, const Operand *OpRa,
CondARM32::Cond Cond) {
IValueT Rd;
if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
return setNeedsTextFixup();
IValueT Rn;
if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
return setNeedsTextFixup();
IValueT Rm;
if (decodeOperand(OpRm, Rm) != DecodedAsRegister)
return setNeedsTextFixup();
IValueT Ra;
if (decodeOperand(OpRa, Ra) != DecodedAsRegister)
return setNeedsTextFixup();
// MLA - ARM section A8.8.114, encoding A1.
// mla{s}<c> <Rd>, <Rn>, <Rm>, <Ra>
//
// cccc0000001sddddaaaammmm1001nnnn where cccc=Cond, s=SetFlags, dddd=Rd,
// aaaa=Ra, mmmm=Rm, and nnnn=Rn.
if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc ||
Rm == RegARM32::Encoded_Reg_pc || Ra == RegARM32::Encoded_Reg_pc)
llvm::report_fatal_error("Mul instruction unpredictable on pc");
constexpr IValueT MlaOpcode = B21;
constexpr bool SetFlags = false;
// Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
emitMulOp(Cond, MlaOpcode, Ra, Rd, Rn, Rm, SetFlags);
}
void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn, void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn,
const Operand *OpSrc1, bool SetFlags, const Operand *OpSrc1, bool SetFlags,
CondARM32::Cond Cond) { CondARM32::Cond Cond) {
......
...@@ -180,6 +180,9 @@ public: ...@@ -180,6 +180,9 @@ public:
void movt(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond); void movt(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond);
void mla(const Operand *OpRd, const Operand *OpRn, const Operand *OpRm,
const Operand *OpRa, CondARM32::Cond Cond);
void mul(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1, void mul(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
bool SetFlags, CondARM32::Cond Cond); bool SetFlags, CondARM32::Cond Cond);
......
...@@ -97,7 +97,7 @@ void InstARM32::emitUsingTextFixup(const Cfg *Func) const { ...@@ -97,7 +97,7 @@ void InstARM32::emitUsingTextFixup(const Cfg *Func) const {
UnimplementedError(Ctx->getFlags()); UnimplementedError(Ctx->getFlags());
return; return;
} }
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
std::string Buffer; std::string Buffer;
llvm::raw_string_ostream StrBuf(Buffer); llvm::raw_string_ostream StrBuf(Buffer);
OstreamLocker L(Ctx); OstreamLocker L(Ctx);
...@@ -201,6 +201,19 @@ void InstARM32Pred::emitFourAddr(const char *Opcode, const InstARM32Pred *Inst, ...@@ -201,6 +201,19 @@ void InstARM32Pred::emitFourAddr(const char *Opcode, const InstARM32Pred *Inst,
Inst->getSrc(2)->emit(Func); Inst->getSrc(2)->emit(Func);
} }
template <InstARM32::InstKindARM32 K>
void InstARM32FourAddrGPR<K>::emitIAS(const Cfg *Func) const {
emitUsingTextFixup(Func);
}
template <> void InstARM32Mla::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 3);
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->mla(getDest(), getSrc(0), getSrc(1), getSrc(2), getPredicate());
if (Asm->needsTextFixup())
emitUsingTextFixup(Func);
}
void InstARM32Pred::emitCmpLike(const char *Opcode, const InstARM32Pred *Inst, void InstARM32Pred::emitCmpLike(const char *Opcode, const InstARM32Pred *Inst,
const Cfg *Func) { const Cfg *Func) {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
...@@ -354,56 +367,56 @@ void InstARM32ThreeAddrGPR<K>::emitIAS(const Cfg *Func) const { ...@@ -354,56 +367,56 @@ void InstARM32ThreeAddrGPR<K>::emitIAS(const Cfg *Func) const {
} }
template <> void InstARM32Adc::emitIAS(const Cfg *Func) const { template <> void InstARM32Adc::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->adc(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); Asm->adc(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
} }
template <> void InstARM32Add::emitIAS(const Cfg *Func) const { template <> void InstARM32Add::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->add(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); Asm->add(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
} }
template <> void InstARM32And::emitIAS(const Cfg *Func) const { template <> void InstARM32And::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->and_(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); Asm->and_(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
} }
template <> void InstARM32Bic::emitIAS(const Cfg *Func) const { template <> void InstARM32Bic::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->bic(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); Asm->bic(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
} }
template <> void InstARM32Eor::emitIAS(const Cfg *Func) const { template <> void InstARM32Eor::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->eor(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); Asm->eor(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
} }
template <> void InstARM32Orr::emitIAS(const Cfg *Func) const { template <> void InstARM32Orr::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->orr(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); Asm->orr(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
} }
template <> void InstARM32Mul::emitIAS(const Cfg *Func) const { template <> void InstARM32Mul::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->mul(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); Asm->mul(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
} }
template <> void InstARM32Sbc::emitIAS(const Cfg *Func) const { template <> void InstARM32Sbc::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->sbc(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); Asm->sbc(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
...@@ -411,14 +424,14 @@ template <> void InstARM32Sbc::emitIAS(const Cfg *Func) const { ...@@ -411,14 +424,14 @@ template <> void InstARM32Sbc::emitIAS(const Cfg *Func) const {
template <> void InstARM32Sdiv::emitIAS(const Cfg *Func) const { template <> void InstARM32Sdiv::emitIAS(const Cfg *Func) const {
assert(!SetFlags); assert(!SetFlags);
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->sdiv(getDest(), getSrc(0), getSrc(1), getPredicate()); Asm->sdiv(getDest(), getSrc(0), getSrc(1), getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
} }
template <> void InstARM32Sub::emitIAS(const Cfg *Func) const { template <> void InstARM32Sub::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->sub(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate()); Asm->sub(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
...@@ -426,7 +439,7 @@ template <> void InstARM32Sub::emitIAS(const Cfg *Func) const { ...@@ -426,7 +439,7 @@ template <> void InstARM32Sub::emitIAS(const Cfg *Func) const {
template <> void InstARM32Udiv::emitIAS(const Cfg *Func) const { template <> void InstARM32Udiv::emitIAS(const Cfg *Func) const {
assert(!SetFlags); assert(!SetFlags);
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->udiv(getDest(), getSrc(0), getSrc(1), getPredicate()); Asm->udiv(getDest(), getSrc(0), getSrc(1), getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
...@@ -530,7 +543,7 @@ void InstARM32CmpLike<K>::emitIAS(const Cfg *Func) const { ...@@ -530,7 +543,7 @@ void InstARM32CmpLike<K>::emitIAS(const Cfg *Func) const {
template <> void InstARM32Cmp::emitIAS(const Cfg *Func) const { template <> void InstARM32Cmp::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 2); assert(getSrcSize() == 2);
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->cmp(getSrc(0), getSrc(1), getPredicate()); Asm->cmp(getSrc(0), getSrc(1), getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
...@@ -538,7 +551,7 @@ template <> void InstARM32Cmp::emitIAS(const Cfg *Func) const { ...@@ -538,7 +551,7 @@ template <> void InstARM32Cmp::emitIAS(const Cfg *Func) const {
template <> void InstARM32Tst::emitIAS(const Cfg *Func) const { template <> void InstARM32Tst::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 2); assert(getSrcSize() == 2);
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->tst(getSrc(0), getSrc(1), getPredicate()); Asm->tst(getSrc(0), getSrc(1), getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
...@@ -728,7 +741,7 @@ void InstARM32Mov::emitSingleDestSingleSource(const Cfg *Func) const { ...@@ -728,7 +741,7 @@ void InstARM32Mov::emitSingleDestSingleSource(const Cfg *Func) const {
} }
void InstARM32Mov::emitIASSingleDestSingleSource(const Cfg *Func) const { void InstARM32Mov::emitIASSingleDestSingleSource(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Variable *Dest = getDest(); Variable *Dest = getDest();
Operand *Src0 = getSrc(0); Operand *Src0 = getSrc(0);
if (Dest->hasReg()) { if (Dest->hasReg()) {
...@@ -777,7 +790,7 @@ void InstARM32Mov::emitIAS(const Cfg *Func) const { ...@@ -777,7 +790,7 @@ void InstARM32Mov::emitIAS(const Cfg *Func) const {
if (!Func->getContext()->getFlags().getAllowUnsafeIas()) if (!Func->getContext()->getFlags().getAllowUnsafeIas())
return emitUsingTextFixup(Func); return emitUsingTextFixup(Func);
assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type."); assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
if (!(isMultiDest() || isMultiSource())) { if (!(isMultiDest() || isMultiSource())) {
// Must be single source/dest. // Must be single source/dest.
emitIASSingleDestSingleSource(Func); emitIASSingleDestSingleSource(Func);
...@@ -831,7 +844,7 @@ void InstARM32Br::emit(const Cfg *Func) const { ...@@ -831,7 +844,7 @@ void InstARM32Br::emit(const Cfg *Func) const {
void InstARM32Br::emitIAS(const Cfg *Func) const { void InstARM32Br::emitIAS(const Cfg *Func) const {
if (!Func->getContext()->getFlags().getAllowUnsafeIas()) if (!Func->getContext()->getFlags().getAllowUnsafeIas())
return emitUsingTextFixup(Func); return emitUsingTextFixup(Func);
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
if (Label) { if (Label) {
Asm->b(Asm->getOrCreateLocalLabel(Label->getNumber()), getPredicate()); Asm->b(Asm->getOrCreateLocalLabel(Label->getNumber()), getPredicate());
} else if (isUnconditionalBranch()) { } else if (isUnconditionalBranch()) {
...@@ -915,7 +928,7 @@ void InstARM32Label::emit(const Cfg *Func) const { ...@@ -915,7 +928,7 @@ void InstARM32Label::emit(const Cfg *Func) const {
} }
void InstARM32Label::emitIAS(const Cfg *Func) const { void InstARM32Label::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->bindLocalLabel(Func, this, Number); Asm->bindLocalLabel(Func, this, Number);
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
...@@ -958,7 +971,7 @@ template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const { ...@@ -958,7 +971,7 @@ template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 1); assert(getSrcSize() == 1);
Variable *Dest = getDest(); Variable *Dest = getDest();
Type DestTy = Dest->getType(); Type DestTy = Dest->getType();
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
if (isVectorType(DestTy) || isScalarFloatingType(DestTy)) if (isVectorType(DestTy) || isScalarFloatingType(DestTy))
// TODO(kschimpf) Handle case. // TODO(kschimpf) Handle case.
Asm->setNeedsTextFixup(); Asm->setNeedsTextFixup();
...@@ -1015,7 +1028,7 @@ template <> void InstARM32Movw::emitIAS(const Cfg *Func) const { ...@@ -1015,7 +1028,7 @@ template <> void InstARM32Movw::emitIAS(const Cfg *Func) const {
if (!Func->getContext()->getFlags().getAllowUnsafeIas()) if (!Func->getContext()->getFlags().getAllowUnsafeIas())
return emitUsingTextFixup(Func); return emitUsingTextFixup(Func);
assert(getSrcSize() == 1); assert(getSrcSize() == 1);
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->movw(getDest(), getSrc(0), getPredicate()); Asm->movw(getDest(), getSrc(0), getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
...@@ -1043,7 +1056,7 @@ template <> void InstARM32Movt::emitIAS(const Cfg *Func) const { ...@@ -1043,7 +1056,7 @@ template <> void InstARM32Movt::emitIAS(const Cfg *Func) const {
if (!Func->getContext()->getFlags().getAllowUnsafeIas()) if (!Func->getContext()->getFlags().getAllowUnsafeIas())
return emitUsingTextFixup(Func); return emitUsingTextFixup(Func);
assert(getSrcSize() == 2); assert(getSrcSize() == 2);
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->movt(getDest(), getSrc(1), getPredicate()); Asm->movt(getDest(), getSrc(1), getPredicate());
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
...@@ -1192,7 +1205,7 @@ void InstARM32Ret::emit(const Cfg *Func) const { ...@@ -1192,7 +1205,7 @@ void InstARM32Ret::emit(const Cfg *Func) const {
} }
void InstARM32Ret::emitIAS(const Cfg *Func) const { void InstARM32Ret::emitIAS(const Cfg *Func) const {
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->bx(RegARM32::Encoded_Reg_lr); Asm->bx(RegARM32::Encoded_Reg_lr);
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
...@@ -1227,7 +1240,7 @@ void InstARM32Str::emit(const Cfg *Func) const { ...@@ -1227,7 +1240,7 @@ void InstARM32Str::emit(const Cfg *Func) const {
void InstARM32Str::emitIAS(const Cfg *Func) const { void InstARM32Str::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 2); assert(getSrcSize() == 2);
Type Ty = getSrc(0)->getType(); Type Ty = getSrc(0)->getType();
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
if (isVectorType(Ty) || isScalarFloatingType(Ty)) if (isVectorType(Ty) || isScalarFloatingType(Ty))
// TODO(kschimpf) Handle case. // TODO(kschimpf) Handle case.
Asm->setNeedsTextFixup(); Asm->setNeedsTextFixup();
...@@ -1288,7 +1301,7 @@ void InstARM32Trap::emit(const Cfg *Func) const { ...@@ -1288,7 +1301,7 @@ void InstARM32Trap::emit(const Cfg *Func) const {
// There isn't a mnemonic for the special NaCl Trap encoding, so dump // There isn't a mnemonic for the special NaCl Trap encoding, so dump
// the raw bytes. // the raw bytes.
Str << "\t.long 0x"; Str << "\t.long 0x";
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
for (uint8_t I : Asm->getNonExecBundlePadding()) { for (uint8_t I : Asm->getNonExecBundlePadding()) {
Str.write_hex(I); Str.write_hex(I);
} }
...@@ -1614,6 +1627,9 @@ template class InstARM32UnaryopGPR<InstARM32::Sxt, true>; ...@@ -1614,6 +1627,9 @@ template class InstARM32UnaryopGPR<InstARM32::Sxt, true>;
template class InstARM32UnaryopGPR<InstARM32::Uxt, true>; template class InstARM32UnaryopGPR<InstARM32::Uxt, true>;
template class InstARM32UnaryopFP<InstARM32::Vsqrt>; template class InstARM32UnaryopFP<InstARM32::Vsqrt>;
template class InstARM32FourAddrGPR<InstARM32::Mla>;
template class InstARM32FourAddrGPR<InstARM32::Mls>;
template class InstARM32CmpLike<InstARM32::Cmp>; template class InstARM32CmpLike<InstARM32::Cmp>;
template class InstARM32CmpLike<InstARM32::Tst>; template class InstARM32CmpLike<InstARM32::Tst>;
......
...@@ -682,6 +682,7 @@ public: ...@@ -682,6 +682,7 @@ public:
return; return;
emitFourAddr(Opcode, this, Func); emitFourAddr(Opcode, this, Func);
} }
void emitIAS(const Cfg *Func) const override;
void dump(const Cfg *Func) const override { void dump(const Cfg *Func) const override {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return; return;
......
...@@ -332,8 +332,7 @@ protected: ...@@ -332,8 +332,7 @@ protected:
// _mov_i1_to_flags is used for bool folding. If "Boolean" is folded, this // _mov_i1_to_flags is used for bool folding. If "Boolean" is folded, this
// method returns true, and sets "CondIfTrue0" and "CondIfTrue1" to the // method returns true, and sets "CondIfTrue0" and "CondIfTrue1" to the
// appropriate ARM condition codes. If "Boolean" is not to be folded, then // appropriate ARM condition codes. If "Boolean" is not to be folded, then
// this // this method returns false.
// method returns false.
bool _mov_i1_to_flags(Operand *Boolean, CondARM32::Cond *CondIfTrue0, bool _mov_i1_to_flags(Operand *Boolean, CondARM32::Cond *CondIfTrue0,
CondARM32::Cond *CondIfTrue1, CondARM32::Cond *CondIfTrue1,
CondARM32::Cond *CondIfFalse); CondARM32::Cond *CondIfFalse);
......
...@@ -68,7 +68,11 @@ define internal i64 @MulTwoI64Regs(i64 %a, i64 %b) { ...@@ -68,7 +68,11 @@ define internal i64 @MulTwoI64Regs(i64 %a, i64 %b) {
; IASM-NEXT: .byte 0x3 ; IASM-NEXT: .byte 0x3
; IASM-NEXT: .byte 0x3 ; IASM-NEXT: .byte 0x3
; IASM-NEXT: .byte 0xe0 ; IASM-NEXT: .byte 0xe0
; IASM-NEXT: mla r1, r2, r1, r3
; IASM-NEXT: .byte 0x92
; IASM-NEXT: .byte 0x31
; IASM-NEXT: .byte 0x21
; IASM-NEXT: .byte 0xe0
; IASM-NEXT: umull r0, r2, r0, r2 ; IASM-NEXT: umull r0, r2, r0, r2
; IASM-NEXT: .byte 0x1 ; IASM-NEXT: .byte 0x1
; IASM-NEXT: .byte 0x20 ; IASM-NEXT: .byte 0x20
......
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