Chromium Code Reviews| Index: src/IceAssemblerARM32.cpp | 
| diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp | 
| index 3dbbb29f0be6fde664abdf2b6b64b253e1f8a8fa..3e15ee6f01c40e5cdb11a65cb265c1ed1b0f3a32 100644 | 
| --- a/src/IceAssemblerARM32.cpp | 
| +++ b/src/IceAssemblerARM32.cpp | 
| @@ -37,6 +37,7 @@ static constexpr IValueT B3 = 1 << 3; | 
| static constexpr IValueT B4 = 1 << 4; | 
| static constexpr IValueT B5 = 1 << 5; | 
| static constexpr IValueT B6 = 1 << 6; | 
| +static constexpr IValueT B7 = 1 << 7; | 
| static constexpr IValueT B21 = 1 << 21; | 
| static constexpr IValueT B24 = 1 << 24; | 
| @@ -58,6 +59,7 @@ static constexpr IValueT kOpcodeShift = 21; | 
| static constexpr IValueT kRdShift = 12; | 
| static constexpr IValueT kRmShift = 0; | 
| static constexpr IValueT kRnShift = 16; | 
| +static constexpr IValueT kRsShift = 8; | 
| static constexpr IValueT kSShift = 20; | 
| static constexpr IValueT kTypeShift = 25; | 
| @@ -348,6 +350,20 @@ void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType, | 
| emitInst(Encoding); | 
| } | 
| +void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, | 
| + IValueT Rn, IValueT Rm, IValueT Rs, bool SetCc) { | 
| + if (!isGPRRegisterDefined(Rd) || !isGPRRegisterDefined(Rn) || | 
| + !isGPRRegisterDefined(Rm) || !isGPRRegisterDefined(Rs) || | 
| + !isConditionDefined(Cond)) | 
| + return setNeedsTextFixup(); | 
| + AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 
| + IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | | 
| + (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | | 
| + (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | | 
| + (Rm << kRmShift); | 
| + emitInst(Encoding); | 
| +} | 
| + | 
| void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, | 
| const Operand *OpSrc1, bool SetFlags, | 
| CondARM32::Cond Cond) { | 
| @@ -609,6 +625,31 @@ void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, | 
| emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); | 
| } | 
| +void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn, | 
| + const Operand *OpSrc1, bool SetFlags, | 
| + 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(OpSrc1, Rm) != DecodedAsRegister) | 
| + return setNeedsTextFixup(); | 
| + // MUL - ARM section A8.8.114, encoding A1. | 
| + // mul{s}<c> <Rd>, <Rn>, <Rm> | 
| + // | 
| + // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, | 
| + // mmmm=Rm, and s=SetFlags. | 
| + if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc || | 
| + Rm == RegARM32::Encoded_Reg_pc) | 
| + llvm::report_fatal_error("Mul instruction unpredictable on pc"); | 
| + // Assembler registers rd, rn, rm are encoded as rn, rm, rs. | 
| + IValueT MulOpcode = 0; | 
| 
 
Jim Stichnoth
2015/10/29 22:17:58
constexpr?
 
Karl
2015/10/30 14:25:56
Done.
 
 | 
| + emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags); | 
| +} | 
| + | 
| void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, | 
| const Operand *OpSrc1, bool SetFlags, | 
| CondARM32::Cond Cond) { |