Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(280)

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1532233002: Add VPUSH/VPOP instructions to the ARM32 integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Remove TODO that doesn't apply anymore. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.cpp » ('j') | src/IceInstARM32.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698