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) {
EmitMulOp(cond, B20, R0, rd, rn, rm);
}
#if 0
// Moved to ARM32::AssemblerARM32::mla
void Assembler::mla(Register rd, Register rn,
Register rm, Register ra, Condition cond) {
// rd <- ra + rn * rm.
// Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
EmitMulOp(cond, B21, ra, rd, rn, rm);
}
#endif
void Assembler::mls(Register rd, Register rn,
......
......@@ -521,9 +521,11 @@ class Assembler : public ValueObject {
// Moved to ARM32::AssemblerARM32::mul()
void mul(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,
Condition cond = AL);
#endif
void mls(Register rd, Register rn, Register rm, Register ra,
Condition cond = AL);
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,
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,
const Operand *OpSrc1, bool SetFlags,
CondARM32::Cond Cond) {
......
......@@ -180,6 +180,9 @@ public:
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,
bool SetFlags, CondARM32::Cond Cond);
......
......@@ -682,6 +682,7 @@ public:
return;
emitFourAddr(Opcode, this, Func);
}
void emitIAS(const Cfg *Func) const override;
void dump(const Cfg *Func) const override {
if (!BuildDefs::dump())
return;
......
......@@ -332,8 +332,7 @@ protected:
// _mov_i1_to_flags is used for bool folding. If "Boolean" is folded, this
// method returns true, and sets "CondIfTrue0" and "CondIfTrue1" to the
// appropriate ARM condition codes. If "Boolean" is not to be folded, then
// this
// method returns false.
// this method returns false.
bool _mov_i1_to_flags(Operand *Boolean, CondARM32::Cond *CondIfTrue0,
CondARM32::Cond *CondIfTrue1,
CondARM32::Cond *CondIfFalse);
......
......@@ -68,7 +68,11 @@ define internal i64 @MulTwoI64Regs(i64 %a, i64 %b) {
; IASM-NEXT: .byte 0x3
; IASM-NEXT: .byte 0x3
; 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: .byte 0x1
; 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