Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// | 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// |
| 2 // | 2 // |
| 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 4 // for details. All rights reserved. Use of this source code is governed by a | 4 // for details. All rights reserved. Use of this source code is governed by a |
| 5 // BSD-style license that can be found in the LICENSE file. | 5 // BSD-style license that can be found in the LICENSE file. |
| 6 // | 6 // |
| 7 // Modified by the Subzero authors. | 7 // Modified by the Subzero authors. |
| 8 // | 8 // |
| 9 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
| 10 // | 10 // |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 108 static constexpr IValueT kDivRmShift = 8; | 108 static constexpr IValueT kDivRmShift = 8; |
| 109 static constexpr IValueT kDivRnShift = 0; | 109 static constexpr IValueT kDivRnShift = 0; |
| 110 | 110 |
| 111 // Type of instruction encoding (bits 25-27). See ARM section A5.1 | 111 // Type of instruction encoding (bits 25-27). See ARM section A5.1 |
| 112 static constexpr IValueT kInstTypeDataRegister = 0; // i.e. 000 | 112 static constexpr IValueT kInstTypeDataRegister = 0; // i.e. 000 |
| 113 static constexpr IValueT kInstTypeDataRegShift = 0; // i.e. 000 | 113 static constexpr IValueT kInstTypeDataRegShift = 0; // i.e. 000 |
| 114 static constexpr IValueT kInstTypeDataImmediate = 1; // i.e. 001 | 114 static constexpr IValueT kInstTypeDataImmediate = 1; // i.e. 001 |
| 115 static constexpr IValueT kInstTypeMemImmediate = 2; // i.e. 010 | 115 static constexpr IValueT kInstTypeMemImmediate = 2; // i.e. 010 |
| 116 static constexpr IValueT kInstTypeRegisterShift = 3; // i.e. 011 | 116 static constexpr IValueT kInstTypeRegisterShift = 3; // i.e. 011 |
| 117 | 117 |
| 118 // Limit on number of registers in a vpush/vpop. | |
| 119 static constexpr SizeT VpushVpopMaxConsecRegs = 16; | |
| 120 | |
| 118 // Offset modifier to current PC for next instruction. The offset is off by 8 | 121 // Offset modifier to current PC for next instruction. The offset is off by 8 |
| 119 // due to the way the ARM CPUs read PC. | 122 // due to the way the ARM CPUs read PC. |
| 120 static constexpr IOffsetT kPCReadOffset = 8; | 123 static constexpr IOffsetT kPCReadOffset = 8; |
| 121 | 124 |
| 122 // Mask to pull out PC offset from branch (b) instruction. | 125 // Mask to pull out PC offset from branch (b) instruction. |
| 123 static constexpr int kBranchOffsetBits = 24; | 126 static constexpr int kBranchOffsetBits = 24; |
| 124 static constexpr IOffsetT kBranchOffsetMask = 0x00ffffff; | 127 static constexpr IOffsetT kBranchOffsetMask = 0x00ffffff; |
| 125 | 128 |
| 126 IValueT encodeBool(bool B) { return B ? 1 : 0; } | 129 IValueT encodeBool(bool B) { return B ? 1 : 0; } |
| 127 | 130 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 192 // actually expect a register. | 195 // actually expect a register. |
| 193 OpEncodingMemEx | 196 OpEncodingMemEx |
| 194 }; | 197 }; |
| 195 | 198 |
| 196 IValueT getEncodedGPRegNum(const Variable *Var) { | 199 IValueT getEncodedGPRegNum(const Variable *Var) { |
| 197 int32_t Reg = Var->getRegNum(); | 200 int32_t Reg = Var->getRegNum(); |
| 198 return llvm::isa<Variable64On32>(Var) ? RegARM32::getI64PairFirstGPRNum(Reg) | 201 return llvm::isa<Variable64On32>(Var) ? RegARM32::getI64PairFirstGPRNum(Reg) |
| 199 : RegARM32::getEncodedGPR(Reg); | 202 : RegARM32::getEncodedGPR(Reg); |
| 200 } | 203 } |
| 201 | 204 |
| 205 IValueT getEncodedSRegNum(const Variable *Var) { | |
| 206 assert(Var->hasReg() && RegARM32::isEncodedSReg(Var->getRegNum())); | |
|
Jim Stichnoth
2015/12/18 00:03:11
Better to change
assert(c1 && c2);
into
assert
Karl
2015/12/18 16:26:50
Done.
| |
| 207 return RegARM32::getEncodedSReg(Var->getRegNum()); | |
| 208 } | |
| 209 | |
| 202 // The way an operand is encoded into a sequence of bits in functions | 210 // The way an operand is encoded into a sequence of bits in functions |
| 203 // encodeOperand and encodeAddress below. | 211 // encodeOperand and encodeAddress below. |
| 204 enum EncodedOperand { | 212 enum EncodedOperand { |
| 205 // Unable to encode, value left undefined. | 213 // Unable to encode, value left undefined. |
| 206 CantEncode = 0, | 214 CantEncode = 0, |
| 207 // Value is register found. | 215 // Value is register found. |
| 208 EncodedAsRegister, | 216 EncodedAsRegister, |
| 209 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 | 217 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 |
| 210 // value. | 218 // value. |
| 211 EncodedAsRotatedImm8, | 219 EncodedAsRotatedImm8, |
| (...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1954 emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags, UmullName); | 1962 emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags, UmullName); |
| 1955 } | 1963 } |
| 1956 | 1964 |
| 1957 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, | 1965 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, |
| 1958 CondARM32::Cond Cond) { | 1966 CondARM32::Cond Cond) { |
| 1959 constexpr const char *UxtName = "uxt"; | 1967 constexpr const char *UxtName = "uxt"; |
| 1960 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21; | 1968 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21; |
| 1961 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName); | 1969 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName); |
| 1962 } | 1970 } |
| 1963 | 1971 |
| 1972 void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode, | |
| 1973 const Variable *OpBaseReg, | |
| 1974 SizeT NumConsecRegs, const char *InstName) { | |
| 1975 | |
| 1976 IValueT BaseReg = getEncodedSRegNum(OpBaseReg); | |
|
John
2015/12/18 00:02:31
Optional: const on everything that's a const
Karl
2015/12/18 16:26:50
Done.
| |
| 1977 IValueT DLastBit = mask(BaseReg, 0, 1); // Last bit of base register. | |
| 1978 IValueT Rd = mask(BaseReg, 1, 4); // Top 4 bits of base register. | |
| 1979 assert(0 < NumConsecRegs && NumConsecRegs <= VpushVpopMaxConsecRegs && | |
|
Jim Stichnoth
2015/12/18 00:03:11
Break this into 3 asserts, as above.
Karl
2015/12/18 16:26:50
Done.
| |
| 1980 (BaseReg + NumConsecRegs) <= RegARM32::getNumSRegs()); | |
| 1981 verifyCondDefined(Cond, InstName); | |
| 1982 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | |
| 1983 IValueT Encoding = Opcode | (Cond << kConditionShift) | DLastBit | | |
| 1984 (Rd << kRdShift) | NumConsecRegs; | |
| 1985 emitInst(Encoding); | |
| 1986 } | |
| 1987 | |
| 1988 void AssemblerARM32::vpop(const Variable *OpBaseReg, SizeT NumConsecRegs, | |
| 1989 CondARM32::Cond Cond) { | |
| 1990 // Note: Current implementation assumes that OpBaseReg is defined using S | |
| 1991 // registers. It doesn't implement the D register form. | |
| 1992 // | |
| 1993 // VPOP - ARM section A8.8.367, encoding A2: | |
| 1994 // vpop<c> <RegList> | |
| 1995 // | |
| 1996 // cccc11001D111101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and | |
| 1997 // iiiiiiii=NumConsecRegs. | |
| 1998 const char *VpopName = "vpop"; | |
|
Jim Stichnoth
2015/12/18 00:03:10
constexpr for these 2 vars
Karl
2015/12/18 16:26:50
Done.
| |
| 1999 IValueT VpopOpcode = B27 | B26 | B23 | B21 | B20 | B19 | B18 | B16 | B11 | B9; | |
| 2000 emitVStackOp(Cond, VpopOpcode, OpBaseReg, NumConsecRegs, VpopName); | |
| 2001 } | |
| 2002 | |
| 2003 void AssemblerARM32::vpush(const Variable *OpBaseReg, SizeT NumConsecRegs, | |
| 2004 CondARM32::Cond Cond) { | |
| 2005 // Note: Current implementation assumes that OpBaseReg is defined using S | |
| 2006 // registers. It doesn't implement the D register form. | |
| 2007 // | |
| 2008 // VPUSH - ARM section A8.8.368, encoding A2: | |
| 2009 // vpush<c> <RegList> | |
| 2010 // | |
| 2011 // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and | |
| 2012 // iiiiiiii=NumConsecRegs. | |
| 2013 const char *VpushName = "vpush"; | |
|
Jim Stichnoth
2015/12/18 00:03:11
constexpr
Karl
2015/12/18 16:26:50
Done.
| |
| 2014 IValueT VpushOpcode = B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9; | |
| 2015 emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs, VpushName); | |
| 2016 } | |
| 2017 | |
| 1964 } // end of namespace ARM32 | 2018 } // end of namespace ARM32 |
| 1965 } // end of namespace Ice | 2019 } // end of namespace Ice |
| OLD | NEW |