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) { |