Index: src/IceAssemblerARM32.cpp |
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp |
index 1dab8b8ce111256a7b83880e64e12a19bcffdf35..d849c54bff0414d7366d32f6d2346b932e75224d 100644 |
--- a/src/IceAssemblerARM32.cpp |
+++ b/src/IceAssemblerARM32.cpp |
@@ -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 |