neon.isa revision 7644
1// -*- mode:c++ -*- 2 3// Copyright (c) 2010 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 if (!neonEnabled(Cpacr, Cpsr, Fpexc)) 43 return disabledFault(); 44 ''' 45}}; 46 47 48def template NeonRegRegRegOpDeclare {{ 49template <class _Element> 50class %(class_name)s : public %(base_class)s 51{ 52 protected: 53 typedef _Element Element; 54 public: 55 // Constructor 56 %(class_name)s(ExtMachInst machInst, 57 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2) 58 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 59 _dest, _op1, _op2) 60 { 61 %(constructor)s; 62 } 63 64 %(BasicExecDeclare)s 65}; 66}}; 67 68def template NeonRegRegRegImmOpDeclare {{ 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 uint64_t _imm) 79 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 80 _dest, _op1, _op2, _imm) 81 { 82 %(constructor)s; 83 } 84 85 %(BasicExecDeclare)s 86}; 87}}; 88 89def template NeonRegRegImmOpDeclare {{ 90template <class _Element> 91class %(class_name)s : public %(base_class)s 92{ 93 protected: 94 typedef _Element Element; 95 public: 96 // Constructor 97 %(class_name)s(ExtMachInst machInst, 98 IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm) 99 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 100 _dest, _op1, _imm) 101 { 102 %(constructor)s; 103 } 104 105 %(BasicExecDeclare)s 106}; 107}}; 108 109def template NeonRegImmOpDeclare {{ 110template <class _Element> 111class %(class_name)s : public %(base_class)s 112{ 113 protected: 114 typedef _Element Element; 115 public: 116 // Constructor 117 %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, uint64_t _imm) 118 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _imm) 119 { 120 %(constructor)s; 121 } 122 123 %(BasicExecDeclare)s 124}; 125}}; 126 127def template NeonRegRegOpDeclare {{ 128template <class _Element> 129class %(class_name)s : public %(base_class)s 130{ 131 protected: 132 typedef _Element Element; 133 public: 134 // Constructor 135 %(class_name)s(ExtMachInst machInst, 136 IntRegIndex _dest, IntRegIndex _op1) 137 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 138 _dest, _op1) 139 { 140 %(constructor)s; 141 } 142 143 %(BasicExecDeclare)s 144}; 145}}; 146 147def template NeonExecDeclare {{ 148 template 149 Fault %(class_name)s<%(targs)s>::execute( 150 %(CPU_exec_context)s *, Trace::InstRecord *) const; 151}}; 152 153output header {{ 154 template <class T> 155 // Implement a less-than-zero function: ltz() 156 // this function exists because some versions of GCC complain when a 157 // comparison is done between a unsigned variable and 0 and for GCC 4.2 158 // there is no way to disable this warning 159 inline bool ltz(T t); 160 161 template <> 162 inline bool ltz(uint8_t) { return false; } 163 template <> 164 inline bool ltz(uint16_t) { return false; } 165 template <> 166 inline bool ltz(uint32_t) { return false; } 167 template <> 168 inline bool ltz(uint64_t) { return false; } 169 template <> 170 inline bool ltz(int8_t v) { return v < 0; } 171 template <> 172 inline bool ltz(int16_t v) { return v < 0; } 173 template <> 174 inline bool ltz(int32_t v) { return v < 0; } 175 template <> 176 inline bool ltz(int64_t v) { return v < 0; } 177}}; 178 179def template NeonEqualRegExecute {{ 180 template <class Element> 181 Fault %(class_name)s<Element>::execute(%(CPU_exec_context)s *xc, 182 Trace::InstRecord *traceData) const 183 { 184 Fault fault = NoFault; 185 %(op_decl)s; 186 %(op_rd)s; 187 188 const unsigned rCount = %(r_count)d; 189 const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element); 190 191 union RegVect { 192 FloatRegBits regs[rCount]; 193 Element elements[eCount]; 194 }; 195 196 if (%(predicate_test)s) 197 { 198 %(code)s; 199 if (fault == NoFault) 200 { 201 %(op_wb)s; 202 } 203 } 204 205 if (fault == NoFault && machInst.itstateMask != 0) { 206 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 207 } 208 209 return fault; 210 } 211}}; 212 213output header {{ 214 uint16_t nextBiggerType(uint8_t); 215 uint32_t nextBiggerType(uint16_t); 216 uint64_t nextBiggerType(uint32_t); 217 int16_t nextBiggerType(int8_t); 218 int32_t nextBiggerType(int16_t); 219 int64_t nextBiggerType(int32_t); 220}}; 221 222def template NeonUnequalRegExecute {{ 223 template <class Element> 224 Fault %(class_name)s<Element>::execute(%(CPU_exec_context)s *xc, 225 Trace::InstRecord *traceData) const 226 { 227 typedef typeof(nextBiggerType((Element)0)) BigElement; 228 Fault fault = NoFault; 229 %(op_decl)s; 230 %(op_rd)s; 231 232 const unsigned rCount = %(r_count)d; 233 const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element); 234 235 union RegVect { 236 FloatRegBits regs[rCount]; 237 Element elements[eCount]; 238 BigElement bigElements[eCount / 2]; 239 }; 240 241 union BigRegVect { 242 FloatRegBits regs[2 * rCount]; 243 BigElement elements[eCount]; 244 }; 245 246 if (%(predicate_test)s) 247 { 248 %(code)s; 249 if (fault == NoFault) 250 { 251 %(op_wb)s; 252 } 253 } 254 255 if (fault == NoFault && machInst.itstateMask != 0) { 256 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 257 } 258 259 return fault; 260 } 261}}; 262