Commit 430e8447 by Karl Schimpf

Add UMULL to ARM integrated assembler.

Also formatted IceCfg.cpp, since it needed it. BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4334 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1422253003 .
parent b9f27229
......@@ -393,7 +393,7 @@ void Assembler::muls(Register rd, Register rn, Register rm, Condition cond) {
}
#if 0
// Moved to ARM32::AssemblerARM32::mla
// Moved to ARM32::AssemblerARM32::mla()
void Assembler::mla(Register rd, Register rn,
Register rm, Register ra, Condition cond) {
// rd <- ra + rn * rm.
......@@ -422,13 +422,14 @@ void Assembler::smull(Register rd_lo, Register rd_hi,
EmitMulOp(cond, B23 | B22, rd_lo, rd_hi, rn, rm);
}
#if 0
// Moved to ARM32::AssemblerARM32::umull()
void Assembler::umull(Register rd_lo, Register rd_hi,
Register rn, Register rm, Condition cond) {
// Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm);
}
#endif
void Assembler::umlal(Register rd_lo, Register rd_hi,
Register rn, Register rm, Condition cond) {
......
......@@ -530,8 +530,11 @@ class Assembler : public ValueObject {
Condition cond = AL);
void smull(Register rd_lo, Register rd_hi, Register rn, Register rm,
Condition cond = AL);
#if 0
// Moved to ARM32::AssemblerARM32::umull();
void umull(Register rd_lo, Register rd_hi, Register rn, Register rm,
Condition cond = AL);
#endif
void smlal(Register rd_lo, Register rd_hi, Register rn, Register rm,
Condition cond = AL);
void umlal(Register rd_lo, Register rd_hi, Register rn, Register rm,
......
......@@ -48,6 +48,7 @@ static constexpr IValueT B15 = 1 << 15;
static constexpr IValueT B20 = 1 << 20;
static constexpr IValueT B21 = 1 << 21;
static constexpr IValueT B22 = 1 << 22;
static constexpr IValueT B23 = 1 << 23;
static constexpr IValueT B24 = 1 << 24;
static constexpr IValueT B25 = 1 << 25;
static constexpr IValueT B26 = 1 << 26;
......@@ -1004,7 +1005,7 @@ void AssemblerARM32::udiv(const Operand *OpRd, const Operand *OpRn,
return setNeedsTextFixup();
if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc ||
Rm == RegARM32::Encoded_Reg_pc)
llvm::report_fatal_error("Sdiv instruction unpredictable on pc");
llvm::report_fatal_error("Udiv instruction unpredictable on pc");
// Assembler registers rd, rn, rm are encoded as rn, rm, rs.
constexpr IValueT Opcode = B21;
emitDivOp(Cond, Opcode, Rd, Rn, Rm);
......@@ -1049,5 +1050,30 @@ void AssemblerARM32::tst(const Operand *OpRn, const Operand *OpSrc1,
emitCompareOp(Opcode, OpRn, OpSrc1, Cond);
}
void AssemblerARM32::umull(const Operand *OpRdLo, const Operand *OpRdHi,
const Operand *OpRn, const Operand *OpRm,
CondARM32::Cond Cond) {
// UMULL - ARM section A8.8.257, encoding A1:
// umull<c> <RdLo>, <RdHi>, <Rn>, <Rm>
//
// cccc0000100shhhhllllmmmm1001nnnn where hhhh=RdHi, llll=RdLo, nnnn=Rn,
// mmmm=Rm, and s=SetFlags
IValueT RdLo;
IValueT RdHi;
IValueT Rn;
IValueT Rm;
if (decodeOperand(OpRdLo, RdLo) != DecodedAsRegister ||
decodeOperand(OpRdHi, RdHi) != DecodedAsRegister ||
decodeOperand(OpRn, Rn) != DecodedAsRegister ||
decodeOperand(OpRm, Rm) != DecodedAsRegister)
return setNeedsTextFixup();
if (RdHi == RegARM32::Encoded_Reg_pc || RdLo == RegARM32::Encoded_Reg_pc ||
Rn == RegARM32::Encoded_Reg_pc || Rm == RegARM32::Encoded_Reg_pc ||
RdHi == RdLo)
llvm::report_fatal_error("Umull instruction unpredictable on pc");
constexpr bool SetFlags = false;
emitMulOp(Cond, B23, RdLo, RdHi, Rn, Rm, SetFlags);
}
} // end of namespace ARM32
} // end of namespace Ice
......@@ -210,6 +210,9 @@ public:
void udiv(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
CondARM32::Cond Cond);
void umull(const Operand *OpRdLo, const Operand *OpRdHi, const Operand *OpRn,
const Operand *OpRm, CondARM32::Cond Cond);
static bool classof(const Assembler *Asm) {
return Asm->getKind() == Asm_ARM32;
}
......
......@@ -1398,6 +1398,14 @@ void InstARM32Umull::emit(const Cfg *Func) const {
getSrc(1)->emit(Func);
}
void InstARM32Umull::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 2);
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->umull(getDest(), DestHi, getSrc(0), getSrc(1), getPredicate());
if (Asm->needsTextFixup())
emitUsingTextFixup(Func);
}
void InstARM32Umull::dump(const Cfg *Func) const {
if (!BuildDefs::dump())
return;
......
......@@ -1086,6 +1086,7 @@ public:
InstARM32Umull(Func, DestLo, DestHi, Src0, Src1, Predicate);
}
void emit(const Cfg *Func) const override;
void emitIAS(const Cfg *Func) const override;
void dump(const Cfg *Func) const override;
static bool classof(const Inst *Inst) { return isClassof(Inst, Umull); }
......
......@@ -73,7 +73,12 @@ define internal i64 @MulTwoI64Regs(i64 %a, i64 %b) {
; IASM-NEXT: .byte 0x31
; IASM-NEXT: .byte 0x21
; IASM-NEXT: .byte 0xe0
; IASM-NEXT: umull r0, r2, r0, r2
; IASM-NEXT: .byte 0x90
; IASM-NEXT: .byte 0x2
; IASM-NEXT: .byte 0x82
; IASM-NEXT: .byte 0xe0
; IASM-NEXT: .byte 0x1
; IASM-NEXT: .byte 0x20
; IASM-NEXT: .byte 0x82
......
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