neon.isa revision 10474:799c8ee4ecba
1// -*- mode:c++ -*- 2 3// Copyright (c) 2010-2012 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Redistribution and use in source and binary forms, with or without 16// modification, are permitted provided that the following conditions are 17// met: redistributions of source code must retain the above copyright 18// notice, this list of conditions and the following disclaimer; 19// redistributions in binary form must reproduce the above copyright 20// notice, this list of conditions and the following disclaimer in the 21// documentation and/or other materials provided with the distribution; 22// neither the name of the copyright holders nor the names of its 23// contributors may be used to endorse or promote products derived from 24// this software without specific prior written permission. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37// 38// Authors: Gabe Black 39 40let {{ 41 simdEnabledCheckCode = ''' 42 { 43 uint32_t issEnCheck; 44 bool trapEnCheck; 45 uint32_t seq; 46 if (!vfpNeonEnabled(seq, Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck, 47 trapEnCheck, xc->tcBase(), Fpexc, true)) 48 {return disabledFault();} 49 if (trapEnCheck) { 50 CPSR cpsrEnCheck = Cpsr; 51 if (cpsrEnCheck.mode == MODE_HYP) { 52 return std::make_shared<UndefinedInstruction>( 53 machInst, issEnCheck, 54 EC_TRAPPED_HCPTR); 55 } else { 56 if (!inSecureState(Scr, Cpsr)) { 57 return std::make_shared<HypervisorTrap>( 58 machInst, issEnCheck, 59 EC_TRAPPED_HCPTR); 60 } 61 } 62 } 63 } 64 ''' 65}}; 66 67 68def template NeonRegRegRegOpDeclare {{ 69template <class _Element> 70class %(class_name)s : public %(base_class)s 71{ 72 protected: 73 typedef _Element Element; 74 public: 75 // Constructor 76 %(class_name)s(ExtMachInst machInst, 77 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2) 78 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 79 _dest, _op1, _op2) 80 { 81 %(constructor)s; 82 if (!(condCode == COND_AL || condCode == COND_UC)) { 83 for (int x = 0; x < _numDestRegs; x++) { 84 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 85 } 86 } 87 } 88 89 %(BasicExecDeclare)s 90}; 91}}; 92 93def template NeonRegRegRegImmOpDeclare {{ 94template <class _Element> 95class %(class_name)s : public %(base_class)s 96{ 97 protected: 98 typedef _Element Element; 99 public: 100 // Constructor 101 %(class_name)s(ExtMachInst machInst, 102 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, 103 uint64_t _imm) 104 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 105 _dest, _op1, _op2, _imm) 106 { 107 %(constructor)s; 108 if (!(condCode == COND_AL || condCode == COND_UC)) { 109 for (int x = 0; x < _numDestRegs; x++) { 110 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 111 } 112 } 113 } 114 115 %(BasicExecDeclare)s 116}; 117}}; 118 119def template NeonRegRegImmOpDeclare {{ 120template <class _Element> 121class %(class_name)s : public %(base_class)s 122{ 123 protected: 124 typedef _Element Element; 125 public: 126 // Constructor 127 %(class_name)s(ExtMachInst machInst, 128 IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm) 129 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 130 _dest, _op1, _imm) 131 { 132 %(constructor)s; 133 if (!(condCode == COND_AL || condCode == COND_UC)) { 134 for (int x = 0; x < _numDestRegs; x++) { 135 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 136 } 137 } 138 } 139 140 %(BasicExecDeclare)s 141}; 142}}; 143 144def template NeonRegImmOpDeclare {{ 145template <class _Element> 146class %(class_name)s : public %(base_class)s 147{ 148 protected: 149 typedef _Element Element; 150 public: 151 // Constructor 152 %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, uint64_t _imm) 153 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _imm) 154 { 155 %(constructor)s; 156 if (!(condCode == COND_AL || condCode == COND_UC)) { 157 for (int x = 0; x < _numDestRegs; x++) { 158 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 159 } 160 } 161 } 162 163 %(BasicExecDeclare)s 164}; 165}}; 166 167def template NeonRegRegOpDeclare {{ 168template <class _Element> 169class %(class_name)s : public %(base_class)s 170{ 171 protected: 172 typedef _Element Element; 173 public: 174 // Constructor 175 %(class_name)s(ExtMachInst machInst, 176 IntRegIndex _dest, IntRegIndex _op1) 177 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 178 _dest, _op1) 179 { 180 %(constructor)s; 181 if (!(condCode == COND_AL || condCode == COND_UC)) { 182 for (int x = 0; x < _numDestRegs; x++) { 183 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 184 } 185 } 186 } 187 188 %(BasicExecDeclare)s 189}; 190}}; 191 192def template NeonExecDeclare {{ 193 template 194 Fault %(class_name)s<%(targs)s>::execute( 195 CPU_EXEC_CONTEXT *, Trace::InstRecord *) const; 196}}; 197 198output header {{ 199 template <class T> 200 // Implement a less-than-zero function: ltz() 201 // this function exists because some versions of GCC complain when a 202 // comparison is done between a unsigned variable and 0 and for GCC 4.2 203 // there is no way to disable this warning 204 inline bool ltz(T t); 205 206 template <> 207 inline bool ltz(uint8_t) { return false; } 208 template <> 209 inline bool ltz(uint16_t) { return false; } 210 template <> 211 inline bool ltz(uint32_t) { return false; } 212 template <> 213 inline bool ltz(uint64_t) { return false; } 214 template <> 215 inline bool ltz(int8_t v) { return v < 0; } 216 template <> 217 inline bool ltz(int16_t v) { return v < 0; } 218 template <> 219 inline bool ltz(int32_t v) { return v < 0; } 220 template <> 221 inline bool ltz(int64_t v) { return v < 0; } 222}}; 223 224def template NeonEqualRegExecute {{ 225 template <class Element> 226 Fault %(class_name)s<Element>::execute(CPU_EXEC_CONTEXT *xc, 227 Trace::InstRecord *traceData) const 228 { 229 Fault fault = NoFault; 230 %(op_decl)s; 231 %(op_rd)s; 232 233 const unsigned rCount = %(r_count)d; 234 const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element); 235 236 union RegVect { 237 FloatRegBits regs[rCount]; 238 Element elements[eCount]; 239 }; 240 241 if (%(predicate_test)s) 242 { 243 %(code)s; 244 if (fault == NoFault) 245 { 246 %(op_wb)s; 247 } 248 } else { 249 xc->setPredicate(false); 250 } 251 252 return fault; 253 } 254}}; 255 256output header {{ 257 template <typename T> 258 struct bigger_type_t; 259 260 template<> struct bigger_type_t<uint8_t> { typedef uint16_t type; }; 261 template<> struct bigger_type_t<uint16_t> { typedef uint32_t type; }; 262 template<> struct bigger_type_t<uint32_t> { typedef uint64_t type; }; 263 264 template<> struct bigger_type_t<int8_t> { typedef int16_t type; }; 265 template<> struct bigger_type_t<int16_t> { typedef int32_t type; }; 266 template<> struct bigger_type_t<int32_t> { typedef int64_t type; }; 267}}; 268 269def template NeonUnequalRegExecute {{ 270 template <class Element> 271 Fault %(class_name)s<Element>::execute(CPU_EXEC_CONTEXT *xc, 272 Trace::InstRecord *traceData) const 273 { 274 typedef typename bigger_type_t<Element>::type BigElement; 275 Fault fault = NoFault; 276 %(op_decl)s; 277 %(op_rd)s; 278 279 const unsigned rCount = %(r_count)d; 280 const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element); 281 282 union RegVect { 283 FloatRegBits regs[rCount]; 284 Element elements[eCount]; 285 BigElement bigElements[eCount / 2]; 286 }; 287 288 union BigRegVect { 289 FloatRegBits regs[2 * rCount]; 290 BigElement elements[eCount]; 291 }; 292 293 if (%(predicate_test)s) 294 { 295 %(code)s; 296 if (fault == NoFault) 297 { 298 %(op_wb)s; 299 } 300 } else { 301 xc->setPredicate(false); 302 } 303 304 return fault; 305 } 306}}; 307