1// Copyright (c) 2017-2018 ARM Limited 2// All rights reserved 3// 4// The license below extends only to copyright in the software and shall 5// not be construed as granting a license to any other intellectual 6// property including but not limited to intellectual property relating 7// to a hardware implementation of the functionality of the software 8// licensed hereunder. You may use the software subject to the license 9// terms below provided that you ensure that this notice is replicated 10// unmodified and in its entirety in all distributions of the software, 11// modified or unmodified, in source code or in binary form. 12// 13// Redistribution and use in source and binary forms, with or without 14// modification, are permitted provided that the following conditions are 15// met: redistributions of source code must retain the above copyright 16// notice, this list of conditions and the following disclaimer; 17// redistributions in binary form must reproduce the above copyright 18// notice, this list of conditions and the following disclaimer in the 19// documentation and/or other materials provided with the distribution; 20// neither the name of the copyright holders nor the names of its 21// contributors may be used to endorse or promote products derived from 22// this software without specific prior written permission. 23// 24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35// 36// Authors: Giacomo Gabrielli 37 38// @file Definition of SVE memory access instructions. 39 40output header {{ 41 42 // Decodes SVE contiguous load instructions, scalar plus scalar form. 43 template <template <typename T1, typename T2> class Base> 44 StaticInstPtr 45 decodeSveContigLoadSSInsts(uint8_t dtype, ExtMachInst machInst, 46 IntRegIndex zt, IntRegIndex pg, IntRegIndex rn, 47 IntRegIndex rm, bool firstFaulting) 48 { 49 const char* mn = firstFaulting ? "ldff1" : "ld1"; 50 switch (dtype) { 51 case 0x0: 52 return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 53 case 0x1: 54 return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 55 case 0x2: 56 return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 57 case 0x3: 58 return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 59 case 0x4: 60 return new Base<int64_t, int32_t>(mn, machInst, zt, pg, rn, rm); 61 case 0x5: 62 return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, rm); 63 case 0x6: 64 return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, rm); 65 case 0x7: 66 return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, rm); 67 case 0x8: 68 return new Base<int64_t, int16_t>(mn, machInst, zt, pg, rn, rm); 69 case 0x9: 70 return new Base<int32_t, int16_t>(mn, machInst, zt, pg, rn, rm); 71 case 0xa: 72 return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, rm); 73 case 0xb: 74 return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, rm); 75 case 0xc: 76 return new Base<int64_t, int8_t>(mn, machInst, zt, pg, rn, rm); 77 case 0xd: 78 return new Base<int32_t, int8_t>(mn, machInst, zt, pg, rn, rm); 79 case 0xe: 80 return new Base<int16_t, int8_t>(mn, machInst, zt, pg, rn, rm); 81 case 0xf: 82 return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, rm); 83 } 84 return new Unknown64(machInst); 85 } 86 87 // Decodes SVE contiguous load instructions, scalar plus immediate form. 88 template <template <typename T1, typename T2> class Base> 89 StaticInstPtr 90 decodeSveContigLoadSIInsts(uint8_t dtype, ExtMachInst machInst, 91 IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
| 1// Copyright (c) 2017-2018 ARM Limited 2// All rights reserved 3// 4// The license below extends only to copyright in the software and shall 5// not be construed as granting a license to any other intellectual 6// property including but not limited to intellectual property relating 7// to a hardware implementation of the functionality of the software 8// licensed hereunder. You may use the software subject to the license 9// terms below provided that you ensure that this notice is replicated 10// unmodified and in its entirety in all distributions of the software, 11// modified or unmodified, in source code or in binary form. 12// 13// Redistribution and use in source and binary forms, with or without 14// modification, are permitted provided that the following conditions are 15// met: redistributions of source code must retain the above copyright 16// notice, this list of conditions and the following disclaimer; 17// redistributions in binary form must reproduce the above copyright 18// notice, this list of conditions and the following disclaimer in the 19// documentation and/or other materials provided with the distribution; 20// neither the name of the copyright holders nor the names of its 21// contributors may be used to endorse or promote products derived from 22// this software without specific prior written permission. 23// 24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35// 36// Authors: Giacomo Gabrielli 37 38// @file Definition of SVE memory access instructions. 39 40output header {{ 41 42 // Decodes SVE contiguous load instructions, scalar plus scalar form. 43 template <template <typename T1, typename T2> class Base> 44 StaticInstPtr 45 decodeSveContigLoadSSInsts(uint8_t dtype, ExtMachInst machInst, 46 IntRegIndex zt, IntRegIndex pg, IntRegIndex rn, 47 IntRegIndex rm, bool firstFaulting) 48 { 49 const char* mn = firstFaulting ? "ldff1" : "ld1"; 50 switch (dtype) { 51 case 0x0: 52 return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 53 case 0x1: 54 return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 55 case 0x2: 56 return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 57 case 0x3: 58 return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 59 case 0x4: 60 return new Base<int64_t, int32_t>(mn, machInst, zt, pg, rn, rm); 61 case 0x5: 62 return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, rm); 63 case 0x6: 64 return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, rm); 65 case 0x7: 66 return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, rm); 67 case 0x8: 68 return new Base<int64_t, int16_t>(mn, machInst, zt, pg, rn, rm); 69 case 0x9: 70 return new Base<int32_t, int16_t>(mn, machInst, zt, pg, rn, rm); 71 case 0xa: 72 return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, rm); 73 case 0xb: 74 return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, rm); 75 case 0xc: 76 return new Base<int64_t, int8_t>(mn, machInst, zt, pg, rn, rm); 77 case 0xd: 78 return new Base<int32_t, int8_t>(mn, machInst, zt, pg, rn, rm); 79 case 0xe: 80 return new Base<int16_t, int8_t>(mn, machInst, zt, pg, rn, rm); 81 case 0xf: 82 return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, rm); 83 } 84 return new Unknown64(machInst); 85 } 86 87 // Decodes SVE contiguous load instructions, scalar plus immediate form. 88 template <template <typename T1, typename T2> class Base> 89 StaticInstPtr 90 decodeSveContigLoadSIInsts(uint8_t dtype, ExtMachInst machInst, 91 IntRegIndex zt, IntRegIndex pg, IntRegIndex rn,
|
92 uint64_t imm, bool firstFaulting,
| 92 uint64_t imm, bool nonFaulting,
|
93 bool replicate = false) 94 {
| 93 bool replicate = false) 94 {
|
95 assert(!(replicate && firstFaulting)); 96 97 const char* mn = replicate ? "ld1r" : 98 (firstFaulting ? "ldff1" : "ld1");
| 95 assert(!(nonFaulting && replicate)); 96 const char* mn = replicate ? "ld1r" : (nonFaulting ? "ldnf1" : "ld1");
|
99 switch (dtype) { 100 case 0x0: 101 return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 102 case 0x1: 103 return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 104 case 0x2: 105 return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 106 case 0x3: 107 return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 108 case 0x4: 109 return new Base<int64_t, int32_t>(mn, machInst, zt, pg, rn, imm); 110 case 0x5: 111 return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, imm); 112 case 0x6: 113 return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, imm); 114 case 0x7: 115 return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, imm); 116 case 0x8: 117 return new Base<int64_t, int16_t>(mn, machInst, zt, pg, rn, imm); 118 case 0x9: 119 return new Base<int32_t, int16_t>(mn, machInst, zt, pg, rn, imm); 120 case 0xa: 121 return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, imm); 122 case 0xb: 123 return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, imm); 124 case 0xc: 125 return new Base<int64_t, int8_t>(mn, machInst, zt, pg, rn, imm); 126 case 0xd: 127 return new Base<int32_t, int8_t>(mn, machInst, zt, pg, rn, imm); 128 case 0xe: 129 return new Base<int16_t, int8_t>(mn, machInst, zt, pg, rn, imm); 130 case 0xf: 131 return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, imm); 132 } 133 return new Unknown64(machInst); 134 } 135 136 // Decodes SVE contiguous store instructions, scalar plus scalar form. 137 template <template <typename T1, typename T2> class Base> 138 StaticInstPtr 139 decodeSveContigStoreSSInsts(uint8_t dtype, ExtMachInst machInst, 140 IntRegIndex zt, IntRegIndex pg, IntRegIndex rn, 141 IntRegIndex rm) 142 { 143 const char* mn = "st1"; 144 switch (dtype) { 145 case 0x0: 146 return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 147 case 0x1: 148 return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 149 case 0x2: 150 return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 151 case 0x3: 152 return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 153 case 0x5: 154 return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, rm); 155 case 0x6: 156 return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, rm); 157 case 0x7: 158 return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, rm); 159 case 0xa: 160 return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, rm); 161 case 0xb: 162 return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, rm); 163 case 0xf: 164 return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, rm); 165 } 166 return new Unknown64(machInst); 167 } 168 169 // Decodes SVE contiguous store instructions, scalar plus immediate form. 170 template <template <typename T1, typename T2> class Base> 171 StaticInstPtr 172 decodeSveContigStoreSIInsts(uint8_t dtype, ExtMachInst machInst, 173 IntRegIndex zt, IntRegIndex pg, IntRegIndex rn, 174 int8_t imm) 175 { 176 const char* mn = "st1"; 177 switch (dtype) { 178 case 0x0: 179 return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 180 case 0x1: 181 return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 182 case 0x2: 183 return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 184 case 0x3: 185 return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 186 case 0x5: 187 return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, imm); 188 case 0x6: 189 return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, imm); 190 case 0x7: 191 return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, imm); 192 case 0xa: 193 return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, imm); 194 case 0xb: 195 return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, imm); 196 case 0xf: 197 return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, imm); 198 } 199 return new Unknown64(machInst); 200 } 201 202 // NOTE: SVE load-and-replicate instructions are decoded with 203 // decodeSveContigLoadSIInsts(...). 204 205}}; 206 207output decoder {{ 208 209 StaticInstPtr 210 decodeSveGatherLoadVIInsts(uint8_t dtype, ExtMachInst machInst, 211 IntRegIndex zt, IntRegIndex pg, IntRegIndex zn, 212 uint64_t imm, bool esizeIs32,
| 97 switch (dtype) { 98 case 0x0: 99 return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 100 case 0x1: 101 return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 102 case 0x2: 103 return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 104 case 0x3: 105 return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 106 case 0x4: 107 return new Base<int64_t, int32_t>(mn, machInst, zt, pg, rn, imm); 108 case 0x5: 109 return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, imm); 110 case 0x6: 111 return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, imm); 112 case 0x7: 113 return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, imm); 114 case 0x8: 115 return new Base<int64_t, int16_t>(mn, machInst, zt, pg, rn, imm); 116 case 0x9: 117 return new Base<int32_t, int16_t>(mn, machInst, zt, pg, rn, imm); 118 case 0xa: 119 return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, imm); 120 case 0xb: 121 return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, imm); 122 case 0xc: 123 return new Base<int64_t, int8_t>(mn, machInst, zt, pg, rn, imm); 124 case 0xd: 125 return new Base<int32_t, int8_t>(mn, machInst, zt, pg, rn, imm); 126 case 0xe: 127 return new Base<int16_t, int8_t>(mn, machInst, zt, pg, rn, imm); 128 case 0xf: 129 return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, imm); 130 } 131 return new Unknown64(machInst); 132 } 133 134 // Decodes SVE contiguous store instructions, scalar plus scalar form. 135 template <template <typename T1, typename T2> class Base> 136 StaticInstPtr 137 decodeSveContigStoreSSInsts(uint8_t dtype, ExtMachInst machInst, 138 IntRegIndex zt, IntRegIndex pg, IntRegIndex rn, 139 IntRegIndex rm) 140 { 141 const char* mn = "st1"; 142 switch (dtype) { 143 case 0x0: 144 return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 145 case 0x1: 146 return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 147 case 0x2: 148 return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 149 case 0x3: 150 return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, rm); 151 case 0x5: 152 return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, rm); 153 case 0x6: 154 return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, rm); 155 case 0x7: 156 return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, rm); 157 case 0xa: 158 return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, rm); 159 case 0xb: 160 return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, rm); 161 case 0xf: 162 return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, rm); 163 } 164 return new Unknown64(machInst); 165 } 166 167 // Decodes SVE contiguous store instructions, scalar plus immediate form. 168 template <template <typename T1, typename T2> class Base> 169 StaticInstPtr 170 decodeSveContigStoreSIInsts(uint8_t dtype, ExtMachInst machInst, 171 IntRegIndex zt, IntRegIndex pg, IntRegIndex rn, 172 int8_t imm) 173 { 174 const char* mn = "st1"; 175 switch (dtype) { 176 case 0x0: 177 return new Base<uint8_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 178 case 0x1: 179 return new Base<uint16_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 180 case 0x2: 181 return new Base<uint32_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 182 case 0x3: 183 return new Base<uint64_t, uint8_t>(mn, machInst, zt, pg, rn, imm); 184 case 0x5: 185 return new Base<uint16_t, uint16_t>(mn, machInst, zt, pg, rn, imm); 186 case 0x6: 187 return new Base<uint32_t, uint16_t>(mn, machInst, zt, pg, rn, imm); 188 case 0x7: 189 return new Base<uint64_t, uint16_t>(mn, machInst, zt, pg, rn, imm); 190 case 0xa: 191 return new Base<uint32_t, uint32_t>(mn, machInst, zt, pg, rn, imm); 192 case 0xb: 193 return new Base<uint64_t, uint32_t>(mn, machInst, zt, pg, rn, imm); 194 case 0xf: 195 return new Base<uint64_t, uint64_t>(mn, machInst, zt, pg, rn, imm); 196 } 197 return new Unknown64(machInst); 198 } 199 200 // NOTE: SVE load-and-replicate instructions are decoded with 201 // decodeSveContigLoadSIInsts(...). 202 203}}; 204 205output decoder {{ 206 207 StaticInstPtr 208 decodeSveGatherLoadVIInsts(uint8_t dtype, ExtMachInst machInst, 209 IntRegIndex zt, IntRegIndex pg, IntRegIndex zn, 210 uint64_t imm, bool esizeIs32,
|
213 bool firstFaulting)
| 211 bool firstFault)
|
214 {
| 212 {
|
215 const char* mn = firstFaulting ? "ldff1" : "ld1";
| 213 const char* mn = firstFault ? "ldff1" : "ld1";
|
216 switch (dtype) { 217 case 0x0: 218 if (esizeIs32) { 219 return new SveIndexedMemVI<int32_t, int8_t,
| 214 switch (dtype) { 215 case 0x0: 216 if (esizeIs32) { 217 return new SveIndexedMemVI<int32_t, int8_t,
|
220 SveGatherLoadVIMicroop>( 221 mn, machInst, MemReadOp, zt, pg, zn, imm);
| 218 SveGatherLoadVIMicroop, 219 SveFirstFaultWritebackMicroop>( 220 mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
|
222 } else { 223 return new SveIndexedMemVI<int64_t, int8_t,
| 221 } else { 222 return new SveIndexedMemVI<int64_t, int8_t,
|
224 SveGatherLoadVIMicroop>( 225 mn, machInst, MemReadOp, zt, pg, zn, imm);
| 223 SveGatherLoadVIMicroop, 224 SveFirstFaultWritebackMicroop>( 225 mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
|
226 } 227 case 0x1: 228 if (esizeIs32) { 229 return new SveIndexedMemVI<uint32_t, uint8_t,
| 226 } 227 case 0x1: 228 if (esizeIs32) { 229 return new SveIndexedMemVI<uint32_t, uint8_t,
|
230 SveGatherLoadVIMicroop>( 231 mn, machInst, MemReadOp, zt, pg, zn, imm);
| 230 SveGatherLoadVIMicroop, 231 SveFirstFaultWritebackMicroop>( 232 mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
|
232 } else { 233 return new SveIndexedMemVI<uint64_t, uint8_t,
| 233 } else { 234 return new SveIndexedMemVI<uint64_t, uint8_t,
|
234 SveGatherLoadVIMicroop>( 235 mn, machInst, MemReadOp, zt, pg, zn, imm);
| 235 SveGatherLoadVIMicroop, 236 SveFirstFaultWritebackMicroop>( 237 mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
|
236 } 237 case 0x2: 238 if (esizeIs32) { 239 return new SveIndexedMemVI<int32_t, int16_t,
| 238 } 239 case 0x2: 240 if (esizeIs32) { 241 return new SveIndexedMemVI<int32_t, int16_t,
|
240 SveGatherLoadVIMicroop>( 241 mn, machInst, MemReadOp, zt, pg, zn, imm);
| 242 SveGatherLoadVIMicroop, 243 SveFirstFaultWritebackMicroop>( 244 mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
|
242 } else { 243 return new SveIndexedMemVI<int64_t, int16_t,
| 245 } else { 246 return new SveIndexedMemVI<int64_t, int16_t,
|
244 SveGatherLoadVIMicroop>( 245 mn, machInst, MemReadOp, zt, pg, zn, imm);
| 247 SveGatherLoadVIMicroop, 248 SveFirstFaultWritebackMicroop>( 249 mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
|
246 } 247 case 0x3: 248 if (esizeIs32) { 249 return new SveIndexedMemVI<uint32_t, uint16_t,
| 250 } 251 case 0x3: 252 if (esizeIs32) { 253 return new SveIndexedMemVI<uint32_t, uint16_t,
|
250 SveGatherLoadVIMicroop>( 251 mn, machInst, MemReadOp, zt, pg, zn, imm);
| 254 SveGatherLoadVIMicroop, 255 SveFirstFaultWritebackMicroop>( 256 mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
|
252 } else { 253 return new SveIndexedMemVI<uint64_t, uint16_t,
| 257 } else { 258 return new SveIndexedMemVI<uint64_t, uint16_t,
|
254 SveGatherLoadVIMicroop>( 255 mn, machInst, MemReadOp, zt, pg, zn, imm);
| 259 SveGatherLoadVIMicroop, 260 SveFirstFaultWritebackMicroop>( 261 mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
|
256 } 257 case 0x4: 258 if (esizeIs32) { 259 break; 260 } else { 261 return new SveIndexedMemVI<int64_t, int32_t,
| 262 } 263 case 0x4: 264 if (esizeIs32) { 265 break; 266 } else { 267 return new SveIndexedMemVI<int64_t, int32_t,
|
262 SveGatherLoadVIMicroop>( 263 mn, machInst, MemReadOp, zt, pg, zn, imm);
| 268 SveGatherLoadVIMicroop, 269 SveFirstFaultWritebackMicroop>( 270 mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
|
264 } 265 case 0x5: 266 if (esizeIs32) { 267 return new SveIndexedMemVI<uint32_t, uint32_t,
| 271 } 272 case 0x5: 273 if (esizeIs32) { 274 return new SveIndexedMemVI<uint32_t, uint32_t,
|
268 SveGatherLoadVIMicroop>( 269 mn, machInst, MemReadOp, zt, pg, zn, imm);
| 275 SveGatherLoadVIMicroop, 276 SveFirstFaultWritebackMicroop>( 277 mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
|
270 } else { 271 return new SveIndexedMemVI<uint64_t, uint32_t,
| 278 } else { 279 return new SveIndexedMemVI<uint64_t, uint32_t,
|
272 SveGatherLoadVIMicroop>( 273 mn, machInst, MemReadOp, zt, pg, zn, imm);
| 280 SveGatherLoadVIMicroop, 281 SveFirstFaultWritebackMicroop>( 282 mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
|
274 } 275 case 0x7: 276 if (esizeIs32) { 277 break; 278 } else { 279 return new SveIndexedMemVI<uint64_t, uint64_t,
| 283 } 284 case 0x7: 285 if (esizeIs32) { 286 break; 287 } else { 288 return new SveIndexedMemVI<uint64_t, uint64_t,
|
280 SveGatherLoadVIMicroop>( 281 mn, machInst, MemReadOp, zt, pg, zn, imm);
| 289 SveGatherLoadVIMicroop, 290 SveFirstFaultWritebackMicroop>( 291 mn, machInst, MemReadOp, zt, pg, zn, imm, firstFault);
|
282 } 283 } 284 return new Unknown64(machInst); 285 } 286 287 StaticInstPtr 288 decodeSveGatherLoadSVInsts(uint8_t dtype, ExtMachInst machInst, 289 IntRegIndex zt, IntRegIndex pg, IntRegIndex rn, 290 IntRegIndex zm, bool esizeIs32, bool offsetIs32, 291 bool offsetIsSigned, bool offsetIsScaled,
| 292 } 293 } 294 return new Unknown64(machInst); 295 } 296 297 StaticInstPtr 298 decodeSveGatherLoadSVInsts(uint8_t dtype, ExtMachInst machInst, 299 IntRegIndex zt, IntRegIndex pg, IntRegIndex rn, 300 IntRegIndex zm, bool esizeIs32, bool offsetIs32, 301 bool offsetIsSigned, bool offsetIsScaled,
|
292 bool firstFaulting)
| 302 bool firstFault)
|
293 {
| 303 {
|
294 const char* mn = firstFaulting ? "ldff1" : "ld1";
| 304 const char* mn = firstFault ? "ldff1" : "ld1";
|
295 switch (dtype) { 296 case 0x0: 297 if (esizeIs32) { 298 return new SveIndexedMemSV<int32_t, int8_t,
| 305 switch (dtype) { 306 case 0x0: 307 if (esizeIs32) { 308 return new SveIndexedMemSV<int32_t, int8_t,
|
299 SveGatherLoadSVMicroop>(
| 309 SveGatherLoadSVMicroop, 310 SveFirstFaultWritebackMicroop>(
|
300 mn, machInst, MemReadOp, zt, pg, rn, zm,
| 311 mn, machInst, MemReadOp, zt, pg, rn, zm,
|
301 offsetIs32, offsetIsSigned, offsetIsScaled);
| 312 offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
|
302 } else { 303 return new SveIndexedMemSV<int64_t, int8_t,
| 313 } else { 314 return new SveIndexedMemSV<int64_t, int8_t,
|
304 SveGatherLoadSVMicroop>(
| 315 SveGatherLoadSVMicroop, 316 SveFirstFaultWritebackMicroop>(
|
305 mn, machInst, MemReadOp, zt, pg, rn, zm,
| 317 mn, machInst, MemReadOp, zt, pg, rn, zm,
|
306 offsetIs32, offsetIsSigned, offsetIsScaled);
| 318 offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
|
307 } 308 case 0x1: 309 if (esizeIs32) { 310 return new SveIndexedMemSV<uint32_t, uint8_t,
| 319 } 320 case 0x1: 321 if (esizeIs32) { 322 return new SveIndexedMemSV<uint32_t, uint8_t,
|
311 SveGatherLoadSVMicroop>(
| 323 SveGatherLoadSVMicroop, 324 SveFirstFaultWritebackMicroop>(
|
312 mn, machInst, MemReadOp, zt, pg, rn, zm,
| 325 mn, machInst, MemReadOp, zt, pg, rn, zm,
|
313 offsetIs32, offsetIsSigned, offsetIsScaled);
| 326 offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
|
314 } else { 315 return new SveIndexedMemSV<uint64_t, uint8_t,
| 327 } else { 328 return new SveIndexedMemSV<uint64_t, uint8_t,
|
316 SveGatherLoadSVMicroop>(
| 329 SveGatherLoadSVMicroop, 330 SveFirstFaultWritebackMicroop>(
|
317 mn, machInst, MemReadOp, zt, pg, rn, zm,
| 331 mn, machInst, MemReadOp, zt, pg, rn, zm,
|
318 offsetIs32, offsetIsSigned, offsetIsScaled);
| 332 offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
|
319 } 320 case 0x2: 321 if (esizeIs32) { 322 return new SveIndexedMemSV<int32_t, int16_t,
| 333 } 334 case 0x2: 335 if (esizeIs32) { 336 return new SveIndexedMemSV<int32_t, int16_t,
|
323 SveGatherLoadSVMicroop>(
| 337 SveGatherLoadSVMicroop, 338 SveFirstFaultWritebackMicroop>(
|
324 mn, machInst, MemReadOp, zt, pg, rn, zm,
| 339 mn, machInst, MemReadOp, zt, pg, rn, zm,
|
325 offsetIs32, offsetIsSigned, offsetIsScaled);
| 340 offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
|
326 } else { 327 return new SveIndexedMemSV<int64_t, int16_t,
| 341 } else { 342 return new SveIndexedMemSV<int64_t, int16_t,
|
328 SveGatherLoadSVMicroop>(
| 343 SveGatherLoadSVMicroop, 344 SveFirstFaultWritebackMicroop>(
|
329 mn, machInst, MemReadOp, zt, pg, rn, zm,
| 345 mn, machInst, MemReadOp, zt, pg, rn, zm,
|
330 offsetIs32, offsetIsSigned, offsetIsScaled);
| 346 offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
|
331 } 332 case 0x3: 333 if (esizeIs32) { 334 return new SveIndexedMemSV<uint32_t, uint16_t,
| 347 } 348 case 0x3: 349 if (esizeIs32) { 350 return new SveIndexedMemSV<uint32_t, uint16_t,
|
335 SveGatherLoadSVMicroop>(
| 351 SveGatherLoadSVMicroop, 352 SveFirstFaultWritebackMicroop>(
|
336 mn, machInst, MemReadOp, zt, pg, rn, zm,
| 353 mn, machInst, MemReadOp, zt, pg, rn, zm,
|
337 offsetIs32, offsetIsSigned, offsetIsScaled);
| 354 offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
|
338 } else { 339 return new SveIndexedMemSV<uint64_t, uint16_t,
| 355 } else { 356 return new SveIndexedMemSV<uint64_t, uint16_t,
|
340 SveGatherLoadSVMicroop>(
| 357 SveGatherLoadSVMicroop, 358 SveFirstFaultWritebackMicroop>(
|
341 mn, machInst, MemReadOp, zt, pg, rn, zm,
| 359 mn, machInst, MemReadOp, zt, pg, rn, zm,
|
342 offsetIs32, offsetIsSigned, offsetIsScaled);
| 360 offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
|
343 } 344 case 0x4: 345 if (esizeIs32) { 346 break; 347 } else { 348 return new SveIndexedMemSV<int64_t, int32_t,
| 361 } 362 case 0x4: 363 if (esizeIs32) { 364 break; 365 } else { 366 return new SveIndexedMemSV<int64_t, int32_t,
|
349 SveGatherLoadSVMicroop>(
| 367 SveGatherLoadSVMicroop, 368 SveFirstFaultWritebackMicroop>(
|
350 mn, machInst, MemReadOp, zt, pg, rn, zm,
| 369 mn, machInst, MemReadOp, zt, pg, rn, zm,
|
351 offsetIs32, offsetIsSigned, offsetIsScaled);
| 370 offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
|
352 } 353 case 0x5: 354 if (esizeIs32) { 355 return new SveIndexedMemSV<uint32_t, uint32_t,
| 371 } 372 case 0x5: 373 if (esizeIs32) { 374 return new SveIndexedMemSV<uint32_t, uint32_t,
|
356 SveGatherLoadSVMicroop>(
| 375 SveGatherLoadSVMicroop, 376 SveFirstFaultWritebackMicroop>(
|
357 mn, machInst, MemReadOp, zt, pg, rn, zm,
| 377 mn, machInst, MemReadOp, zt, pg, rn, zm,
|
358 offsetIs32, offsetIsSigned, offsetIsScaled);
| 378 offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
|
359 } else { 360 return new SveIndexedMemSV<uint64_t, uint32_t,
| 379 } else { 380 return new SveIndexedMemSV<uint64_t, uint32_t,
|
361 SveGatherLoadSVMicroop>(
| 381 SveGatherLoadSVMicroop, 382 SveFirstFaultWritebackMicroop>(
|
362 mn, machInst, MemReadOp, zt, pg, rn, zm,
| 383 mn, machInst, MemReadOp, zt, pg, rn, zm,
|
363 offsetIs32, offsetIsSigned, offsetIsScaled);
| 384 offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
|
364 } 365 case 0x7: 366 if (esizeIs32) { 367 break; 368 } else { 369 return new SveIndexedMemSV<uint64_t, uint64_t,
| 385 } 386 case 0x7: 387 if (esizeIs32) { 388 break; 389 } else { 390 return new SveIndexedMemSV<uint64_t, uint64_t,
|
370 SveGatherLoadSVMicroop>(
| 391 SveGatherLoadSVMicroop, 392 SveFirstFaultWritebackMicroop>(
|
371 mn, machInst, MemReadOp, zt, pg, rn, zm,
| 393 mn, machInst, MemReadOp, zt, pg, rn, zm,
|
372 offsetIs32, offsetIsSigned, offsetIsScaled);
| 394 offsetIs32, offsetIsSigned, offsetIsScaled, firstFault);
|
373 } 374 } 375 return new Unknown64(machInst); 376 } 377 378 StaticInstPtr 379 decodeSveScatterStoreVIInsts(uint8_t msz, ExtMachInst machInst, 380 IntRegIndex zt, IntRegIndex pg, 381 IntRegIndex zn, uint64_t imm, 382 bool esizeIs32) 383 { 384 const char* mn = "st1"; 385 switch (msz) { 386 case 0x0: 387 if (esizeIs32) { 388 return new SveIndexedMemVI<uint32_t, uint8_t,
| 395 } 396 } 397 return new Unknown64(machInst); 398 } 399 400 StaticInstPtr 401 decodeSveScatterStoreVIInsts(uint8_t msz, ExtMachInst machInst, 402 IntRegIndex zt, IntRegIndex pg, 403 IntRegIndex zn, uint64_t imm, 404 bool esizeIs32) 405 { 406 const char* mn = "st1"; 407 switch (msz) { 408 case 0x0: 409 if (esizeIs32) { 410 return new SveIndexedMemVI<uint32_t, uint8_t,
|
389 SveScatterStoreVIMicroop>( 390 mn, machInst, MemWriteOp, zt, pg, zn, imm);
| 411 SveScatterStoreVIMicroop, 412 SveFirstFaultWritebackMicroop>( 413 mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
|
391 } else { 392 return new SveIndexedMemVI<uint64_t, uint8_t,
| 414 } else { 415 return new SveIndexedMemVI<uint64_t, uint8_t,
|
393 SveScatterStoreVIMicroop>( 394 mn, machInst, MemWriteOp, zt, pg, zn, imm);
| 416 SveScatterStoreVIMicroop, 417 SveFirstFaultWritebackMicroop>( 418 mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
|
395 } 396 case 0x1: 397 if (esizeIs32) { 398 return new SveIndexedMemVI<uint32_t, uint16_t,
| 419 } 420 case 0x1: 421 if (esizeIs32) { 422 return new SveIndexedMemVI<uint32_t, uint16_t,
|
399 SveScatterStoreVIMicroop>( 400 mn, machInst, MemWriteOp, zt, pg, zn, imm);
| 423 SveScatterStoreVIMicroop, 424 SveFirstFaultWritebackMicroop>( 425 mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
|
401 } else { 402 return new SveIndexedMemVI<uint64_t, uint16_t,
| 426 } else { 427 return new SveIndexedMemVI<uint64_t, uint16_t,
|
403 SveScatterStoreVIMicroop>( 404 mn, machInst, MemWriteOp, zt, pg, zn, imm);
| 428 SveScatterStoreVIMicroop, 429 SveFirstFaultWritebackMicroop>( 430 mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
|
405 } 406 case 0x2: 407 if (esizeIs32) { 408 return new SveIndexedMemVI<uint32_t, uint32_t,
| 431 } 432 case 0x2: 433 if (esizeIs32) { 434 return new SveIndexedMemVI<uint32_t, uint32_t,
|
409 SveScatterStoreVIMicroop>( 410 mn, machInst, MemWriteOp, zt, pg, zn, imm);
| 435 SveScatterStoreVIMicroop, 436 SveFirstFaultWritebackMicroop>( 437 mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
|
411 } else { 412 return new SveIndexedMemVI<uint64_t, uint32_t,
| 438 } else { 439 return new SveIndexedMemVI<uint64_t, uint32_t,
|
413 SveScatterStoreVIMicroop>( 414 mn, machInst, MemWriteOp, zt, pg, zn, imm);
| 440 SveScatterStoreVIMicroop, 441 SveFirstFaultWritebackMicroop>( 442 mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
|
415 } 416 case 0x3: 417 if (esizeIs32) { 418 break; 419 } else { 420 return new SveIndexedMemVI<uint64_t, uint64_t,
| 443 } 444 case 0x3: 445 if (esizeIs32) { 446 break; 447 } else { 448 return new SveIndexedMemVI<uint64_t, uint64_t,
|
421 SveScatterStoreVIMicroop>( 422 mn, machInst, MemWriteOp, zt, pg, zn, imm);
| 449 SveScatterStoreVIMicroop, 450 SveFirstFaultWritebackMicroop>( 451 mn, machInst, MemWriteOp, zt, pg, zn, imm, false);
|
423 } 424 } 425 return new Unknown64(machInst); 426 } 427 428 StaticInstPtr 429 decodeSveScatterStoreSVInsts(uint8_t msz, ExtMachInst machInst, 430 IntRegIndex zt, IntRegIndex pg, 431 IntRegIndex rn, IntRegIndex zm, 432 bool esizeIs32, bool offsetIs32, 433 bool offsetIsSigned, bool offsetIsScaled) 434 { 435 const char* mn = "st1"; 436 switch (msz) { 437 case 0x0: 438 if (esizeIs32) { 439 return new SveIndexedMemSV<uint32_t, uint8_t,
| 452 } 453 } 454 return new Unknown64(machInst); 455 } 456 457 StaticInstPtr 458 decodeSveScatterStoreSVInsts(uint8_t msz, ExtMachInst machInst, 459 IntRegIndex zt, IntRegIndex pg, 460 IntRegIndex rn, IntRegIndex zm, 461 bool esizeIs32, bool offsetIs32, 462 bool offsetIsSigned, bool offsetIsScaled) 463 { 464 const char* mn = "st1"; 465 switch (msz) { 466 case 0x0: 467 if (esizeIs32) { 468 return new SveIndexedMemSV<uint32_t, uint8_t,
|
440 SveScatterStoreSVMicroop>(
| 469 SveScatterStoreSVMicroop, 470 SveFirstFaultWritebackMicroop>(
|
441 mn, machInst, MemWriteOp, zt, pg, rn, zm,
| 471 mn, machInst, MemWriteOp, zt, pg, rn, zm,
|
442 offsetIs32, offsetIsSigned, offsetIsScaled);
| 472 offsetIs32, offsetIsSigned, offsetIsScaled, false);
|
443 } else { 444 return new SveIndexedMemSV<uint64_t, uint8_t,
| 473 } else { 474 return new SveIndexedMemSV<uint64_t, uint8_t,
|
445 SveScatterStoreSVMicroop>(
| 475 SveScatterStoreSVMicroop, 476 SveFirstFaultWritebackMicroop>(
|
446 mn, machInst, MemWriteOp, zt, pg, rn, zm,
| 477 mn, machInst, MemWriteOp, zt, pg, rn, zm,
|
447 offsetIs32, offsetIsSigned, offsetIsScaled);
| 478 offsetIs32, offsetIsSigned, offsetIsScaled, false);
|
448 } 449 case 0x1: 450 if (esizeIs32) { 451 return new SveIndexedMemSV<uint32_t, uint16_t,
| 479 } 480 case 0x1: 481 if (esizeIs32) { 482 return new SveIndexedMemSV<uint32_t, uint16_t,
|
452 SveScatterStoreSVMicroop>(
| 483 SveScatterStoreSVMicroop, 484 SveFirstFaultWritebackMicroop>(
|
453 mn, machInst, MemWriteOp, zt, pg, rn, zm,
| 485 mn, machInst, MemWriteOp, zt, pg, rn, zm,
|
454 offsetIs32, offsetIsSigned, offsetIsScaled);
| 486 offsetIs32, offsetIsSigned, offsetIsScaled, false);
|
455 } else { 456 return new SveIndexedMemSV<uint64_t, uint16_t,
| 487 } else { 488 return new SveIndexedMemSV<uint64_t, uint16_t,
|
457 SveScatterStoreSVMicroop>(
| 489 SveScatterStoreSVMicroop, 490 SveFirstFaultWritebackMicroop>(
|
458 mn, machInst, MemWriteOp, zt, pg, rn, zm,
| 491 mn, machInst, MemWriteOp, zt, pg, rn, zm,
|
459 offsetIs32, offsetIsSigned, offsetIsScaled);
| 492 offsetIs32, offsetIsSigned, offsetIsScaled, false);
|
460 } 461 case 0x2: 462 if (esizeIs32) { 463 return new SveIndexedMemSV<uint32_t, uint32_t,
| 493 } 494 case 0x2: 495 if (esizeIs32) { 496 return new SveIndexedMemSV<uint32_t, uint32_t,
|
464 SveScatterStoreSVMicroop>(
| 497 SveScatterStoreSVMicroop, 498 SveFirstFaultWritebackMicroop>(
|
465 mn, machInst, MemWriteOp, zt, pg, rn, zm,
| 499 mn, machInst, MemWriteOp, zt, pg, rn, zm,
|
466 offsetIs32, offsetIsSigned, offsetIsScaled);
| 500 offsetIs32, offsetIsSigned, offsetIsScaled, false);
|
467 } else { 468 return new SveIndexedMemSV<uint64_t, uint32_t,
| 501 } else { 502 return new SveIndexedMemSV<uint64_t, uint32_t,
|
469 SveScatterStoreSVMicroop>(
| 503 SveScatterStoreSVMicroop, 504 SveFirstFaultWritebackMicroop>(
|
470 mn, machInst, MemWriteOp, zt, pg, rn, zm,
| 505 mn, machInst, MemWriteOp, zt, pg, rn, zm,
|
471 offsetIs32, offsetIsSigned, offsetIsScaled);
| 506 offsetIs32, offsetIsSigned, offsetIsScaled, false);
|
472 } 473 case 0x3: 474 if (esizeIs32) { 475 break; 476 } else { 477 return new SveIndexedMemSV<uint64_t, uint64_t,
| 507 } 508 case 0x3: 509 if (esizeIs32) { 510 break; 511 } else { 512 return new SveIndexedMemSV<uint64_t, uint64_t,
|
478 SveScatterStoreSVMicroop>(
| 513 SveScatterStoreSVMicroop, 514 SveFirstFaultWritebackMicroop>(
|
479 mn, machInst, MemWriteOp, zt, pg, rn, zm,
| 515 mn, machInst, MemWriteOp, zt, pg, rn, zm,
|
480 offsetIs32, offsetIsSigned, offsetIsScaled);
| 516 offsetIs32, offsetIsSigned, offsetIsScaled, false);
|
481 } 482 } 483 return new Unknown64(machInst); 484 } 485 486}}; 487 488 489let {{ 490 491 header_output = '' 492 exec_output = '' 493 decoders = { 'Generic': {} } 494 495 SPAlignmentCheckCode = ''' 496 if (this->baseIsSP && bits(XBase, 3, 0) && 497 SPAlignmentCheckEnabled(xc->tcBase())) { 498 return std::make_shared<SPAlignmentFault>(); 499 } 500 ''' 501 502 def emitSveMemFillSpill(isPred): 503 global header_output, exec_output, decoders 504 eaCode = SPAlignmentCheckCode + ''' 505 int memAccessSize = %(memacc_size)s; 506 EA = XBase + ((int64_t) imm * %(memacc_size)s)''' % { 507 'memacc_size': 'eCount / 8' if isPred else 'eCount'}
| 517 } 518 } 519 return new Unknown64(machInst); 520 } 521 522}}; 523 524 525let {{ 526 527 header_output = '' 528 exec_output = '' 529 decoders = { 'Generic': {} } 530 531 SPAlignmentCheckCode = ''' 532 if (this->baseIsSP && bits(XBase, 3, 0) && 533 SPAlignmentCheckEnabled(xc->tcBase())) { 534 return std::make_shared<SPAlignmentFault>(); 535 } 536 ''' 537 538 def emitSveMemFillSpill(isPred): 539 global header_output, exec_output, decoders 540 eaCode = SPAlignmentCheckCode + ''' 541 int memAccessSize = %(memacc_size)s; 542 EA = XBase + ((int64_t) imm * %(memacc_size)s)''' % { 543 'memacc_size': 'eCount / 8' if isPred else 'eCount'}
|
| 544 loadRdEnableCode = ''' 545 auto rdEn = std::vector<bool>(); 546 '''
|
508 if isPred: 509 loadMemAccCode = ''' 510 int index = 0; 511 uint8_t byte; 512 for (int i = 0; i < eCount / 8; i++) { 513 byte = memDataView[i]; 514 for (int j = 0; j < 8; j++, index++) { 515 PDest_x[index] = (byte >> j) & 1; 516 } 517 } 518 ''' 519 storeMemAccCode = ''' 520 int index = 0; 521 uint8_t byte; 522 for (int i = 0; i < eCount / 8; i++) { 523 byte = 0; 524 for (int j = 0; j < 8; j++, index++) { 525 byte |= PDest_x[index] << j; 526 } 527 memDataView[i] = byte; 528 } 529 ''' 530 storeWrEnableCode = ''' 531 auto wrEn = std::vector<bool>(eCount / 8, true); 532 ''' 533 else: 534 loadMemAccCode = ''' 535 for (int i = 0; i < eCount; i++) { 536 AA64FpDest_x[i] = memDataView[i]; 537 } 538 ''' 539 storeMemAccCode = ''' 540 for (int i = 0; i < eCount; i++) { 541 memDataView[i] = AA64FpDest_x[i]; 542 } 543 ''' 544 storeWrEnableCode = ''' 545 auto wrEn = std::vector<bool>(sizeof(MemElemType) * eCount, true); 546 ''' 547 loadIop = InstObjParams('ldr', 548 'SveLdrPred' if isPred else 'SveLdrVec', 549 'SveMemPredFillSpill' if isPred else 'SveMemVecFillSpill', 550 {'tpl_header': '', 551 'tpl_args': '', 552 'memacc_code': loadMemAccCode, 553 'ea_code' : sveEnabledCheckCode + eaCode,
| 547 if isPred: 548 loadMemAccCode = ''' 549 int index = 0; 550 uint8_t byte; 551 for (int i = 0; i < eCount / 8; i++) { 552 byte = memDataView[i]; 553 for (int j = 0; j < 8; j++, index++) { 554 PDest_x[index] = (byte >> j) & 1; 555 } 556 } 557 ''' 558 storeMemAccCode = ''' 559 int index = 0; 560 uint8_t byte; 561 for (int i = 0; i < eCount / 8; i++) { 562 byte = 0; 563 for (int j = 0; j < 8; j++, index++) { 564 byte |= PDest_x[index] << j; 565 } 566 memDataView[i] = byte; 567 } 568 ''' 569 storeWrEnableCode = ''' 570 auto wrEn = std::vector<bool>(eCount / 8, true); 571 ''' 572 else: 573 loadMemAccCode = ''' 574 for (int i = 0; i < eCount; i++) { 575 AA64FpDest_x[i] = memDataView[i]; 576 } 577 ''' 578 storeMemAccCode = ''' 579 for (int i = 0; i < eCount; i++) { 580 memDataView[i] = AA64FpDest_x[i]; 581 } 582 ''' 583 storeWrEnableCode = ''' 584 auto wrEn = std::vector<bool>(sizeof(MemElemType) * eCount, true); 585 ''' 586 loadIop = InstObjParams('ldr', 587 'SveLdrPred' if isPred else 'SveLdrVec', 588 'SveMemPredFillSpill' if isPred else 'SveMemVecFillSpill', 589 {'tpl_header': '', 590 'tpl_args': '', 591 'memacc_code': loadMemAccCode, 592 'ea_code' : sveEnabledCheckCode + eaCode,
|
| 593 'rden_code' : loadRdEnableCode, 594 'fault_code' : '',
|
554 'fa_code' : ''}, 555 ['IsMemRef', 'IsLoad']) 556 storeIop = InstObjParams('str', 557 'SveStrPred' if isPred else 'SveStrVec', 558 'SveMemPredFillSpill' if isPred else 'SveMemVecFillSpill', 559 {'tpl_header': '', 560 'tpl_args': '', 561 'wren_code': storeWrEnableCode, 562 'memacc_code': storeMemAccCode, 563 'ea_code' : sveEnabledCheckCode + eaCode, 564 'fa_code' : ''}, 565 ['IsMemRef', 'IsStore']) 566 header_output += SveMemFillSpillOpDeclare.subst(loadIop) 567 header_output += SveMemFillSpillOpDeclare.subst(storeIop) 568 exec_output += ( 569 SveContigLoadExecute.subst(loadIop) + 570 SveContigLoadInitiateAcc.subst(loadIop) + 571 SveContigLoadCompleteAcc.subst(loadIop) + 572 SveContigStoreExecute.subst(storeIop) + 573 SveContigStoreInitiateAcc.subst(storeIop) + 574 SveContigStoreCompleteAcc.subst(storeIop)) 575 576 loadTplArgs = ( 577 ('uint8_t', 'uint8_t'), 578 ('uint16_t', 'uint8_t'), 579 ('uint32_t', 'uint8_t'), 580 ('uint64_t', 'uint8_t'), 581 ('int64_t', 'int32_t'), 582 ('uint16_t', 'uint16_t'), 583 ('uint32_t', 'uint16_t'), 584 ('uint64_t', 'uint16_t'), 585 ('int64_t', 'int16_t'), 586 ('int32_t', 'int16_t'), 587 ('uint32_t', 'uint32_t'), 588 ('uint64_t', 'uint32_t'), 589 ('int64_t', 'int8_t'), 590 ('int32_t', 'int8_t'), 591 ('int16_t', 'int8_t'), 592 ('uint64_t', 'uint64_t'), 593 ) 594 595 storeTplArgs = ( 596 ('uint8_t', 'uint8_t'), 597 ('uint16_t', 'uint8_t'), 598 ('uint32_t', 'uint8_t'), 599 ('uint64_t', 'uint8_t'), 600 ('uint16_t', 'uint16_t'), 601 ('uint32_t', 'uint16_t'), 602 ('uint64_t', 'uint16_t'), 603 ('uint32_t', 'uint32_t'), 604 ('uint64_t', 'uint32_t'), 605 ('uint64_t', 'uint64_t'), 606 ) 607 608 gatherLoadTplArgs = ( 609 ('int32_t', 'int8_t'), 610 ('int64_t', 'int8_t'), 611 ('uint32_t', 'uint8_t'), 612 ('uint64_t', 'uint8_t'), 613 ('int32_t', 'int16_t'), 614 ('int64_t', 'int16_t'), 615 ('uint32_t', 'uint16_t'), 616 ('uint64_t', 'uint16_t'), 617 ('int64_t', 'int32_t'), 618 ('uint32_t', 'uint32_t'), 619 ('uint64_t', 'uint32_t'), 620 ('uint64_t', 'uint64_t'), 621 ) 622 623 scatterStoreTplArgs = ( 624 ('uint32_t', 'uint8_t'), 625 ('uint64_t', 'uint8_t'), 626 ('uint32_t', 'uint16_t'), 627 ('uint64_t', 'uint16_t'), 628 ('uint32_t', 'uint32_t'), 629 ('uint64_t', 'uint32_t'), 630 ('uint64_t', 'uint64_t'), 631 ) 632 633 # Generates definitions for SVE contiguous loads 634 def emitSveContigMemInsts(offsetIsImm): 635 global header_output, exec_output, decoders
| 595 'fa_code' : ''}, 596 ['IsMemRef', 'IsLoad']) 597 storeIop = InstObjParams('str', 598 'SveStrPred' if isPred else 'SveStrVec', 599 'SveMemPredFillSpill' if isPred else 'SveMemVecFillSpill', 600 {'tpl_header': '', 601 'tpl_args': '', 602 'wren_code': storeWrEnableCode, 603 'memacc_code': storeMemAccCode, 604 'ea_code' : sveEnabledCheckCode + eaCode, 605 'fa_code' : ''}, 606 ['IsMemRef', 'IsStore']) 607 header_output += SveMemFillSpillOpDeclare.subst(loadIop) 608 header_output += SveMemFillSpillOpDeclare.subst(storeIop) 609 exec_output += ( 610 SveContigLoadExecute.subst(loadIop) + 611 SveContigLoadInitiateAcc.subst(loadIop) + 612 SveContigLoadCompleteAcc.subst(loadIop) + 613 SveContigStoreExecute.subst(storeIop) + 614 SveContigStoreInitiateAcc.subst(storeIop) + 615 SveContigStoreCompleteAcc.subst(storeIop)) 616 617 loadTplArgs = ( 618 ('uint8_t', 'uint8_t'), 619 ('uint16_t', 'uint8_t'), 620 ('uint32_t', 'uint8_t'), 621 ('uint64_t', 'uint8_t'), 622 ('int64_t', 'int32_t'), 623 ('uint16_t', 'uint16_t'), 624 ('uint32_t', 'uint16_t'), 625 ('uint64_t', 'uint16_t'), 626 ('int64_t', 'int16_t'), 627 ('int32_t', 'int16_t'), 628 ('uint32_t', 'uint32_t'), 629 ('uint64_t', 'uint32_t'), 630 ('int64_t', 'int8_t'), 631 ('int32_t', 'int8_t'), 632 ('int16_t', 'int8_t'), 633 ('uint64_t', 'uint64_t'), 634 ) 635 636 storeTplArgs = ( 637 ('uint8_t', 'uint8_t'), 638 ('uint16_t', 'uint8_t'), 639 ('uint32_t', 'uint8_t'), 640 ('uint64_t', 'uint8_t'), 641 ('uint16_t', 'uint16_t'), 642 ('uint32_t', 'uint16_t'), 643 ('uint64_t', 'uint16_t'), 644 ('uint32_t', 'uint32_t'), 645 ('uint64_t', 'uint32_t'), 646 ('uint64_t', 'uint64_t'), 647 ) 648 649 gatherLoadTplArgs = ( 650 ('int32_t', 'int8_t'), 651 ('int64_t', 'int8_t'), 652 ('uint32_t', 'uint8_t'), 653 ('uint64_t', 'uint8_t'), 654 ('int32_t', 'int16_t'), 655 ('int64_t', 'int16_t'), 656 ('uint32_t', 'uint16_t'), 657 ('uint64_t', 'uint16_t'), 658 ('int64_t', 'int32_t'), 659 ('uint32_t', 'uint32_t'), 660 ('uint64_t', 'uint32_t'), 661 ('uint64_t', 'uint64_t'), 662 ) 663 664 scatterStoreTplArgs = ( 665 ('uint32_t', 'uint8_t'), 666 ('uint64_t', 'uint8_t'), 667 ('uint32_t', 'uint16_t'), 668 ('uint64_t', 'uint16_t'), 669 ('uint32_t', 'uint32_t'), 670 ('uint64_t', 'uint32_t'), 671 ('uint64_t', 'uint64_t'), 672 ) 673 674 # Generates definitions for SVE contiguous loads 675 def emitSveContigMemInsts(offsetIsImm): 676 global header_output, exec_output, decoders
|
| 677 # First-faulting instructions only have a scalar plus scalar form, 678 # while non-faulting instructions only a scalar plus immediate form, so 679 # `offsetIsImm` is used to determine which class of instructions is 680 # generated 681 firstFaulting = not offsetIsImm
|
636 tplHeader = 'template <class RegElemType, class MemElemType>' 637 tplArgs = '<RegElemType, MemElemType>' 638 eaCode = SPAlignmentCheckCode + ''' 639 int memAccessSize = eCount * sizeof(MemElemType); 640 EA = XBase + ''' 641 if offsetIsImm: 642 eaCode += '((int64_t) this->imm * eCount * sizeof(MemElemType))' 643 else: 644 eaCode += '(XOffset * sizeof(MemElemType));'
| 682 tplHeader = 'template <class RegElemType, class MemElemType>' 683 tplArgs = '<RegElemType, MemElemType>' 684 eaCode = SPAlignmentCheckCode + ''' 685 int memAccessSize = eCount * sizeof(MemElemType); 686 EA = XBase + ''' 687 if offsetIsImm: 688 eaCode += '((int64_t) this->imm * eCount * sizeof(MemElemType))' 689 else: 690 eaCode += '(XOffset * sizeof(MemElemType));'
|
| 691 loadRdEnableCode = ''' 692 auto rdEn = std::vector<bool>(sizeof(MemElemType) * eCount, true); 693 for (int i = 0; i < eCount; i++) { 694 if (!GpOp_x[i]) { 695 for (int j = 0; j < sizeof(MemElemType); j++) { 696 rdEn[sizeof(MemElemType) * i + j] = false; 697 } 698 } 699 } 700 '''
|
645 loadMemAccCode = ''' 646 for (int i = 0; i < eCount; i++) { 647 if (GpOp_x[i]) { 648 AA64FpDest_x[i] = memDataView[i]; 649 } else { 650 AA64FpDest_x[i] = 0; 651 } 652 } 653 ''' 654 storeMemAccCode = ''' 655 for (int i = 0; i < eCount; i++) { 656 if (GpOp_x[i]) { 657 memDataView[i] = AA64FpDest_x[i]; 658 } else { 659 memDataView[i] = 0; 660 for (int j = 0; j < sizeof(MemElemType); j++) { 661 wrEn[sizeof(MemElemType) * i + j] = false; 662 } 663 } 664 } 665 ''' 666 storeWrEnableCode = ''' 667 auto wrEn = std::vector<bool>(sizeof(MemElemType) * eCount, true); 668 '''
| 701 loadMemAccCode = ''' 702 for (int i = 0; i < eCount; i++) { 703 if (GpOp_x[i]) { 704 AA64FpDest_x[i] = memDataView[i]; 705 } else { 706 AA64FpDest_x[i] = 0; 707 } 708 } 709 ''' 710 storeMemAccCode = ''' 711 for (int i = 0; i < eCount; i++) { 712 if (GpOp_x[i]) { 713 memDataView[i] = AA64FpDest_x[i]; 714 } else { 715 memDataView[i] = 0; 716 for (int j = 0; j < sizeof(MemElemType); j++) { 717 wrEn[sizeof(MemElemType) * i + j] = false; 718 } 719 } 720 } 721 ''' 722 storeWrEnableCode = ''' 723 auto wrEn = std::vector<bool>(sizeof(MemElemType) * eCount, true); 724 '''
|
| 725 ffrReadBackCode = ''' 726 auto& firstFaultReg = Ffr;''' 727 fautlingLoadmemAccCode = ''' 728 for (int i = 0; i < eCount; i++) { 729 if (GpOp_x[i] && firstFaultReg[i * sizeof(RegElemType)]) { 730 AA64FpDest_x[i] = memDataView[i]; 731 } else { 732 AA64FpDest_x[i] = 0; 733 } 734 } 735 ''' 736 nonFaultingCode = 'true ||' 737 faultCode = ''' 738 Addr fault_addr; 739 if (fault == NoFault || getFaultVAddr(fault, fault_addr)) { 740 unsigned fault_elem_index; 741 if (fault != NoFault) { 742 assert(fault_addr >= EA); 743 fault_elem_index = (fault_addr - EA) / sizeof(MemElemType); 744 } else { 745 fault_elem_index = eCount + 1; 746 } 747 int first_active_index; 748 for (first_active_index = 0; 749 first_active_index < eCount && !(GpOp_x[first_active_index]); 750 first_active_index++); 751 if (%s first_active_index < fault_elem_index) { 752 for (int i = 0; i < eCount; i++) { 753 for (int j = 0; j < sizeof(RegElemType); j++) { 754 if (i < fault_elem_index) { 755 Ffr_ub[i * sizeof(RegElemType) + j] = FfrAux_x[i]; 756 } else { 757 Ffr_ub[i * sizeof(RegElemType) + j] = 0; 758 } 759 } 760 } 761 fault = NoFault; 762 if (first_active_index >= fault_elem_index) { 763 // non-faulting load needs this 764 xc->setMemAccPredicate(false); 765 } 766 } 767 } 768 ''' % ('' if firstFaulting else nonFaultingCode) 769
|
669 loadIop = InstObjParams('ld1', 670 'SveContigLoadSI' if offsetIsImm else 'SveContigLoadSS', 671 'SveContigMemSI' if offsetIsImm else 'SveContigMemSS', 672 {'tpl_header': tplHeader, 673 'tpl_args': tplArgs,
| 770 loadIop = InstObjParams('ld1', 771 'SveContigLoadSI' if offsetIsImm else 'SveContigLoadSS', 772 'SveContigMemSI' if offsetIsImm else 'SveContigMemSS', 773 {'tpl_header': tplHeader, 774 'tpl_args': tplArgs,
|
| 775 'rden_code' : loadRdEnableCode,
|
674 'memacc_code': loadMemAccCode, 675 'ea_code' : sveEnabledCheckCode + eaCode,
| 776 'memacc_code': loadMemAccCode, 777 'ea_code' : sveEnabledCheckCode + eaCode,
|
| 778 'fault_code' : '',
|
676 'fa_code' : ''}, 677 ['IsMemRef', 'IsLoad']) 678 storeIop = InstObjParams('st1', 679 'SveContigStoreSI' if offsetIsImm else 'SveContigStoreSS', 680 'SveContigMemSI' if offsetIsImm else 'SveContigMemSS', 681 {'tpl_header': tplHeader, 682 'tpl_args': tplArgs, 683 'wren_code': storeWrEnableCode, 684 'memacc_code': storeMemAccCode, 685 'ea_code' : sveEnabledCheckCode + eaCode, 686 'fa_code' : ''}, 687 ['IsMemRef', 'IsStore'])
| 779 'fa_code' : ''}, 780 ['IsMemRef', 'IsLoad']) 781 storeIop = InstObjParams('st1', 782 'SveContigStoreSI' if offsetIsImm else 'SveContigStoreSS', 783 'SveContigMemSI' if offsetIsImm else 'SveContigMemSS', 784 {'tpl_header': tplHeader, 785 'tpl_args': tplArgs, 786 'wren_code': storeWrEnableCode, 787 'memacc_code': storeMemAccCode, 788 'ea_code' : sveEnabledCheckCode + eaCode, 789 'fa_code' : ''}, 790 ['IsMemRef', 'IsStore'])
|
| 791 faultIop = InstObjParams('ldff1' if firstFaulting else 'ldnf1', 792 'SveContigFFLoadSS' if firstFaulting else 'SveContigNFLoadSI', 793 'SveContigMemSS' if firstFaulting else 'SveContigMemSI', 794 {'tpl_header': tplHeader, 795 'tpl_args': tplArgs, 796 'rden_code' : loadRdEnableCode, 797 'memacc_code': fautlingLoadmemAccCode, 798 'ea_code' : sveEnabledCheckCode + eaCode, 799 'fault_code' : faultCode, 800 'fa_code' : ''}, 801 ['IsMemRef', 'IsLoad']) 802 faultIop.snippets['memacc_code'] = (ffrReadBackCode + 803 faultIop.snippets['memacc_code'])
|
688 if offsetIsImm: 689 header_output += SveContigMemSIOpDeclare.subst(loadIop) 690 header_output += SveContigMemSIOpDeclare.subst(storeIop)
| 804 if offsetIsImm: 805 header_output += SveContigMemSIOpDeclare.subst(loadIop) 806 header_output += SveContigMemSIOpDeclare.subst(storeIop)
|
| 807 header_output += SveContigMemSIOpDeclare.subst(faultIop)
|
691 else: 692 header_output += SveContigMemSSOpDeclare.subst(loadIop) 693 header_output += SveContigMemSSOpDeclare.subst(storeIop)
| 808 else: 809 header_output += SveContigMemSSOpDeclare.subst(loadIop) 810 header_output += SveContigMemSSOpDeclare.subst(storeIop)
|
| 811 header_output += SveContigMemSSOpDeclare.subst(faultIop)
|
694 exec_output += ( 695 SveContigLoadExecute.subst(loadIop) + 696 SveContigLoadInitiateAcc.subst(loadIop) + 697 SveContigLoadCompleteAcc.subst(loadIop) + 698 SveContigStoreExecute.subst(storeIop) + 699 SveContigStoreInitiateAcc.subst(storeIop) +
| 812 exec_output += ( 813 SveContigLoadExecute.subst(loadIop) + 814 SveContigLoadInitiateAcc.subst(loadIop) + 815 SveContigLoadCompleteAcc.subst(loadIop) + 816 SveContigStoreExecute.subst(storeIop) + 817 SveContigStoreInitiateAcc.subst(storeIop) +
|
700 SveContigStoreCompleteAcc.subst(storeIop))
| 818 SveContigStoreCompleteAcc.subst(storeIop) + 819 SveContigLoadExecute.subst(faultIop) + 820 SveContigLoadInitiateAcc.subst(faultIop) + 821 SveContigLoadCompleteAcc.subst(faultIop)) 822
|
701 for args in loadTplArgs: 702 substDict = {'tpl_args': '<%s>' % ', '.join(args), 703 'class_name': 'SveContigLoadSI' if offsetIsImm 704 else 'SveContigLoadSS'} 705 exec_output += SveContigMemExecDeclare.subst(substDict) 706 for args in storeTplArgs: 707 substDict = {'tpl_args': '<%s>' % ', '.join(args), 708 'class_name': 'SveContigStoreSI' if offsetIsImm 709 else 'SveContigStoreSS'} 710 exec_output += SveContigMemExecDeclare.subst(substDict)
| 823 for args in loadTplArgs: 824 substDict = {'tpl_args': '<%s>' % ', '.join(args), 825 'class_name': 'SveContigLoadSI' if offsetIsImm 826 else 'SveContigLoadSS'} 827 exec_output += SveContigMemExecDeclare.subst(substDict) 828 for args in storeTplArgs: 829 substDict = {'tpl_args': '<%s>' % ', '.join(args), 830 'class_name': 'SveContigStoreSI' if offsetIsImm 831 else 'SveContigStoreSS'} 832 exec_output += SveContigMemExecDeclare.subst(substDict)
|
| 833 for args in loadTplArgs: 834 substDict = {'tpl_args': '<%s>' % ', '.join(args), 835 'class_name': 'SveContigFFLoadSS' if firstFaulting 836 else 'SveContigNFLoadSI'} 837 exec_output += SveContigMemExecDeclare.subst(substDict)
|
711
| 838
|
| 839
|
712 # Generates definitions for SVE load-and-replicate instructions 713 def emitSveLoadAndRepl(): 714 global header_output, exec_output, decoders 715 tplHeader = 'template <class RegElemType, class MemElemType>' 716 tplArgs = '<RegElemType, MemElemType>' 717 eaCode = SPAlignmentCheckCode + ''' 718 EA = XBase + imm * sizeof(MemElemType);''' 719 memAccCode = ''' 720 for (int i = 0; i < eCount; i++) { 721 if (GpOp_x[i]) { 722 AA64FpDest_x[i] = memData; 723 } else { 724 AA64FpDest_x[i] = 0; 725 } 726 } 727 ''' 728 iop = InstObjParams('ld1r', 729 'SveLoadAndRepl', 730 'SveContigMemSI', 731 {'tpl_header': tplHeader, 732 'tpl_args': tplArgs, 733 'memacc_code': memAccCode, 734 'ea_code' : sveEnabledCheckCode + eaCode, 735 'fa_code' : ''}, 736 ['IsMemRef', 'IsLoad']) 737 header_output += SveContigMemSIOpDeclare.subst(iop) 738 exec_output += ( 739 SveLoadAndReplExecute.subst(iop) + 740 SveLoadAndReplInitiateAcc.subst(iop) + 741 SveLoadAndReplCompleteAcc.subst(iop)) 742 for args in loadTplArgs: 743 substDict = {'tpl_args': '<%s>' % ', '.join(args), 744 'class_name': 'SveLoadAndRepl'} 745 exec_output += SveContigMemExecDeclare.subst(substDict) 746 747 class IndexedAddrForm: 748 VEC_PLUS_IMM = 0 749 SCA_PLUS_VEC = 1 750 751 # Generates definitions for the transfer microops of SVE indexed memory 752 # operations (gather loads, scatter stores) 753 def emitSveIndexedMemMicroops(indexed_addr_form): 754 assert indexed_addr_form in (IndexedAddrForm.VEC_PLUS_IMM, 755 IndexedAddrForm.SCA_PLUS_VEC) 756 global header_output, exec_output, decoders 757 tplHeader = 'template <class RegElemType, class MemElemType>' 758 tplArgs = '<RegElemType, MemElemType>' 759 if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM: 760 eaCode = ''' 761 EA = AA64FpBase_x[elemIndex] + imm * sizeof(MemElemType)''' 762 else: 763 eaCode = ''' 764 uint64_t offset = AA64FpOffset_x[elemIndex]; 765 if (offsetIs32) { 766 offset &= (1ULL << 32) - 1; 767 } 768 if (offsetIsSigned) { 769 offset = sext<32>(offset); 770 } 771 if (offsetIsScaled) { 772 offset *= sizeof(MemElemType); 773 } 774 EA = XBase + offset''' 775 loadMemAccCode = '''
| 840 # Generates definitions for SVE load-and-replicate instructions 841 def emitSveLoadAndRepl(): 842 global header_output, exec_output, decoders 843 tplHeader = 'template <class RegElemType, class MemElemType>' 844 tplArgs = '<RegElemType, MemElemType>' 845 eaCode = SPAlignmentCheckCode + ''' 846 EA = XBase + imm * sizeof(MemElemType);''' 847 memAccCode = ''' 848 for (int i = 0; i < eCount; i++) { 849 if (GpOp_x[i]) { 850 AA64FpDest_x[i] = memData; 851 } else { 852 AA64FpDest_x[i] = 0; 853 } 854 } 855 ''' 856 iop = InstObjParams('ld1r', 857 'SveLoadAndRepl', 858 'SveContigMemSI', 859 {'tpl_header': tplHeader, 860 'tpl_args': tplArgs, 861 'memacc_code': memAccCode, 862 'ea_code' : sveEnabledCheckCode + eaCode, 863 'fa_code' : ''}, 864 ['IsMemRef', 'IsLoad']) 865 header_output += SveContigMemSIOpDeclare.subst(iop) 866 exec_output += ( 867 SveLoadAndReplExecute.subst(iop) + 868 SveLoadAndReplInitiateAcc.subst(iop) + 869 SveLoadAndReplCompleteAcc.subst(iop)) 870 for args in loadTplArgs: 871 substDict = {'tpl_args': '<%s>' % ', '.join(args), 872 'class_name': 'SveLoadAndRepl'} 873 exec_output += SveContigMemExecDeclare.subst(substDict) 874 875 class IndexedAddrForm: 876 VEC_PLUS_IMM = 0 877 SCA_PLUS_VEC = 1 878 879 # Generates definitions for the transfer microops of SVE indexed memory 880 # operations (gather loads, scatter stores) 881 def emitSveIndexedMemMicroops(indexed_addr_form): 882 assert indexed_addr_form in (IndexedAddrForm.VEC_PLUS_IMM, 883 IndexedAddrForm.SCA_PLUS_VEC) 884 global header_output, exec_output, decoders 885 tplHeader = 'template <class RegElemType, class MemElemType>' 886 tplArgs = '<RegElemType, MemElemType>' 887 if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM: 888 eaCode = ''' 889 EA = AA64FpBase_x[elemIndex] + imm * sizeof(MemElemType)''' 890 else: 891 eaCode = ''' 892 uint64_t offset = AA64FpOffset_x[elemIndex]; 893 if (offsetIs32) { 894 offset &= (1ULL << 32) - 1; 895 } 896 if (offsetIsSigned) { 897 offset = sext<32>(offset); 898 } 899 if (offsetIsScaled) { 900 offset *= sizeof(MemElemType); 901 } 902 EA = XBase + offset''' 903 loadMemAccCode = '''
|
776 if (GpOp_x[elemIndex]) { 777 AA64FpDest_x[elemIndex] = memData; 778 } else { 779 AA64FpDest_x[elemIndex] = 0; 780 }
| 904 AA64FpDest_x[elemIndex] = memData;
|
781 ''' 782 storeMemAccCode = ''' 783 memData = AA64FpDest_x[elemIndex]; 784 '''
| 905 ''' 906 storeMemAccCode = ''' 907 memData = AA64FpDest_x[elemIndex]; 908 '''
|
785 predCheckCode = 'GpOp_x[elemIndex]'
| 909 predCheckCode = 'GpOp_x[index]' 910 faultStatusSetCode = 'PUreg0_x[elemIndex] = 1;' 911 faultStatusResetCode = 'PUreg0_x[elemIndex] = 0;'
|
786 loadIop = InstObjParams('ld1', 787 ('SveGatherLoadVIMicroop' 788 if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM 789 else 'SveGatherLoadSVMicroop'), 790 'MicroOp', 791 {'tpl_header': tplHeader, 792 'tpl_args': tplArgs, 793 'memacc_code': loadMemAccCode, 794 'ea_code' : sveEnabledCheckCode + eaCode,
| 912 loadIop = InstObjParams('ld1', 913 ('SveGatherLoadVIMicroop' 914 if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM 915 else 'SveGatherLoadSVMicroop'), 916 'MicroOp', 917 {'tpl_header': tplHeader, 918 'tpl_args': tplArgs, 919 'memacc_code': loadMemAccCode, 920 'ea_code' : sveEnabledCheckCode + eaCode,
|
| 921 'fault_status_set_code' : faultStatusSetCode, 922 'fault_status_reset_code' : faultStatusResetCode,
|
795 'pred_check_code' : predCheckCode, 796 'fa_code' : ''}, 797 ['IsMicroop', 'IsMemRef', 'IsLoad']) 798 storeIop = InstObjParams('st1', 799 ('SveScatterStoreVIMicroop' 800 if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM 801 else 'SveScatterStoreSVMicroop'), 802 'MicroOp', 803 {'tpl_header': tplHeader, 804 'tpl_args': tplArgs, 805 'memacc_code': storeMemAccCode, 806 'ea_code' : sveEnabledCheckCode + eaCode, 807 'pred_check_code' : predCheckCode, 808 'fa_code' : ''}, 809 ['IsMicroop', 'IsMemRef', 'IsStore']) 810 if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM: 811 header_output += SveIndexedMemVIMicroopDeclare.subst(loadIop) 812 header_output += SveIndexedMemVIMicroopDeclare.subst(storeIop) 813 else: 814 header_output += SveIndexedMemSVMicroopDeclare.subst(loadIop) 815 header_output += SveIndexedMemSVMicroopDeclare.subst(storeIop) 816 exec_output += ( 817 SveGatherLoadMicroopExecute.subst(loadIop) + 818 SveGatherLoadMicroopInitiateAcc.subst(loadIop) + 819 SveGatherLoadMicroopCompleteAcc.subst(loadIop) + 820 SveScatterStoreMicroopExecute.subst(storeIop) + 821 SveScatterStoreMicroopInitiateAcc.subst(storeIop) + 822 SveScatterStoreMicroopCompleteAcc.subst(storeIop)) 823 for args in gatherLoadTplArgs: 824 substDict = {'tpl_args': '<%s>' % ', '.join(args), 825 'class_name': ( 826 'SveGatherLoadVIMicroop' 827 if indexed_addr_form == \ 828 IndexedAddrForm.VEC_PLUS_IMM 829 else 'SveGatherLoadSVMicroop')} 830 # TODO: this should become SveMemExecDeclare 831 exec_output += SveContigMemExecDeclare.subst(substDict) 832 for args in scatterStoreTplArgs: 833 substDict = {'tpl_args': '<%s>' % ', '.join(args), 834 'class_name': ( 835 'SveScatterStoreVIMicroop' 836 if indexed_addr_form == \ 837 IndexedAddrForm.VEC_PLUS_IMM 838 else 'SveScatterStoreSVMicroop')} 839 # TODO: this should become SveMemExecDeclare 840 exec_output += SveContigMemExecDeclare.subst(substDict) 841
| 923 'pred_check_code' : predCheckCode, 924 'fa_code' : ''}, 925 ['IsMicroop', 'IsMemRef', 'IsLoad']) 926 storeIop = InstObjParams('st1', 927 ('SveScatterStoreVIMicroop' 928 if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM 929 else 'SveScatterStoreSVMicroop'), 930 'MicroOp', 931 {'tpl_header': tplHeader, 932 'tpl_args': tplArgs, 933 'memacc_code': storeMemAccCode, 934 'ea_code' : sveEnabledCheckCode + eaCode, 935 'pred_check_code' : predCheckCode, 936 'fa_code' : ''}, 937 ['IsMicroop', 'IsMemRef', 'IsStore']) 938 if indexed_addr_form == IndexedAddrForm.VEC_PLUS_IMM: 939 header_output += SveIndexedMemVIMicroopDeclare.subst(loadIop) 940 header_output += SveIndexedMemVIMicroopDeclare.subst(storeIop) 941 else: 942 header_output += SveIndexedMemSVMicroopDeclare.subst(loadIop) 943 header_output += SveIndexedMemSVMicroopDeclare.subst(storeIop) 944 exec_output += ( 945 SveGatherLoadMicroopExecute.subst(loadIop) + 946 SveGatherLoadMicroopInitiateAcc.subst(loadIop) + 947 SveGatherLoadMicroopCompleteAcc.subst(loadIop) + 948 SveScatterStoreMicroopExecute.subst(storeIop) + 949 SveScatterStoreMicroopInitiateAcc.subst(storeIop) + 950 SveScatterStoreMicroopCompleteAcc.subst(storeIop)) 951 for args in gatherLoadTplArgs: 952 substDict = {'tpl_args': '<%s>' % ', '.join(args), 953 'class_name': ( 954 'SveGatherLoadVIMicroop' 955 if indexed_addr_form == \ 956 IndexedAddrForm.VEC_PLUS_IMM 957 else 'SveGatherLoadSVMicroop')} 958 # TODO: this should become SveMemExecDeclare 959 exec_output += SveContigMemExecDeclare.subst(substDict) 960 for args in scatterStoreTplArgs: 961 substDict = {'tpl_args': '<%s>' % ', '.join(args), 962 'class_name': ( 963 'SveScatterStoreVIMicroop' 964 if indexed_addr_form == \ 965 IndexedAddrForm.VEC_PLUS_IMM 966 else 'SveScatterStoreSVMicroop')} 967 # TODO: this should become SveMemExecDeclare 968 exec_output += SveContigMemExecDeclare.subst(substDict) 969
|
| 970 firstFaultTplArgs = ('int32_t', 'int64_t', 'uint32_t', 'uint64_t') 971 972 def emitSveFirstFaultWritebackMicroop(): 973 global header_output, exec_output, decoders 974 tplHeader = 'template <class RegElemType>' 975 tplArgs = '<RegElemType>' 976 faultStatusCheckCode = 'PUreg0_x[index]' 977 firstFaultResetCode = ''' 978 for(int j = 0; j < sizeof(RegElemType); j++) { 979 Ffr_ub[index * sizeof(RegElemType) + j] = 0; 980 } 981 ''' 982 firstFaultForwardCode = ''' 983 for(int j = 0; j < sizeof(RegElemType); j++) { 984 Ffr_ub[index * sizeof(RegElemType) + j] = FfrAux_x[index]; 985 } 986 ''' 987 iop = InstObjParams('ldff1', 988 'SveFirstFaultWritebackMicroop', 989 'MicroOp', 990 {'tpl_header': tplHeader, 991 'tpl_args': tplArgs, 992 'fault_status_check_code' : faultStatusCheckCode, 993 'first_fault_reset_code' : firstFaultResetCode, 994 'first_fault_forward_code' : firstFaultForwardCode}, 995 ['IsMicroop']) 996 header_output += SveFirstFaultWritebackMicroopDeclare.subst(iop) 997 exec_output += SveFirstFaultWritebackMicroopExecute.subst(iop) 998 for args in firstFaultTplArgs: 999 substDict = {'targs': args, 1000 'class_name' : 'SveFirstFaultWritebackMicroop' } 1001 exec_output += SveOpExecDeclare.subst(substDict) 1002
|
842 # Generates definitions for the first microop of SVE gather loads, required 843 # to propagate the source vector register to the transfer microops 844 def emitSveGatherLoadCpySrcVecMicroop(): 845 global header_output, exec_output, decoders 846 code = sveEnabledCheckCode + ''' 847 unsigned eCount = ArmStaticInst::getCurSveVecLen<uint8_t>( 848 xc->tcBase()); 849 for (unsigned i = 0; i < eCount; i++) { 850 AA64FpUreg0_ub[i] = AA64FpOp1_ub[i]; 851 }''' 852 iop = InstObjParams('ld1', 853 'SveGatherLoadCpySrcVecMicroop', 854 'MicroOp', 855 {'code': code}, 856 ['IsMicroop']) 857 header_output += SveGatherLoadCpySrcVecMicroopDeclare.subst(iop) 858 exec_output += SveGatherLoadCpySrcVecMicroopExecute.subst(iop) 859 860 # LD1[S]{B,H,W,D} (scalar plus immediate) 861 # ST1[S]{B,H,W,D} (scalar plus immediate)
| 1003 # Generates definitions for the first microop of SVE gather loads, required 1004 # to propagate the source vector register to the transfer microops 1005 def emitSveGatherLoadCpySrcVecMicroop(): 1006 global header_output, exec_output, decoders 1007 code = sveEnabledCheckCode + ''' 1008 unsigned eCount = ArmStaticInst::getCurSveVecLen<uint8_t>( 1009 xc->tcBase()); 1010 for (unsigned i = 0; i < eCount; i++) { 1011 AA64FpUreg0_ub[i] = AA64FpOp1_ub[i]; 1012 }''' 1013 iop = InstObjParams('ld1', 1014 'SveGatherLoadCpySrcVecMicroop', 1015 'MicroOp', 1016 {'code': code}, 1017 ['IsMicroop']) 1018 header_output += SveGatherLoadCpySrcVecMicroopDeclare.subst(iop) 1019 exec_output += SveGatherLoadCpySrcVecMicroopExecute.subst(iop) 1020 1021 # LD1[S]{B,H,W,D} (scalar plus immediate) 1022 # ST1[S]{B,H,W,D} (scalar plus immediate)
|
| 1023 # LDNF1[S]{B,H,W,D} (scalar plus immediate)
|
862 emitSveContigMemInsts(True) 863 # LD1[S]{B,H,W,D} (scalar plus scalar) 864 # ST1[S]{B,H,W,D} (scalar plus scalar)
| 1024 emitSveContigMemInsts(True) 1025 # LD1[S]{B,H,W,D} (scalar plus scalar) 1026 # ST1[S]{B,H,W,D} (scalar plus scalar)
|
| 1027 # LDFF1[S]{B,H,W,D} (scalar plus vector)
|
865 emitSveContigMemInsts(False) 866 867 # LD1R[S]{B,H,W,D} 868 emitSveLoadAndRepl() 869 870 # LDR (predicate), STR (predicate) 871 emitSveMemFillSpill(True) 872 # LDR (vector), STR (vector) 873 emitSveMemFillSpill(False) 874 875 # LD1[S]{B,H,W,D} (vector plus immediate) 876 # ST1[S]{B,H,W,D} (vector plus immediate)
| 1028 emitSveContigMemInsts(False) 1029 1030 # LD1R[S]{B,H,W,D} 1031 emitSveLoadAndRepl() 1032 1033 # LDR (predicate), STR (predicate) 1034 emitSveMemFillSpill(True) 1035 # LDR (vector), STR (vector) 1036 emitSveMemFillSpill(False) 1037 1038 # LD1[S]{B,H,W,D} (vector plus immediate) 1039 # ST1[S]{B,H,W,D} (vector plus immediate)
|
| 1040 # LDFF1[S]{B,H,W,D} (scalar plus immediate)
|
877 emitSveIndexedMemMicroops(IndexedAddrForm.VEC_PLUS_IMM) 878 # LD1[S]{B,H,W,D} (scalar plus vector) 879 # ST1[S]{B,H,W,D} (scalar plus vector)
| 1041 emitSveIndexedMemMicroops(IndexedAddrForm.VEC_PLUS_IMM) 1042 # LD1[S]{B,H,W,D} (scalar plus vector) 1043 # ST1[S]{B,H,W,D} (scalar plus vector)
|
| 1044 # LDFF1[S]{B,H,W,D} (scalar plus vector)
|
880 emitSveIndexedMemMicroops(IndexedAddrForm.SCA_PLUS_VEC) 881
| 1045 emitSveIndexedMemMicroops(IndexedAddrForm.SCA_PLUS_VEC) 1046
|
| 1047 # FFR writeback microop for gather loads 1048 emitSveFirstFaultWritebackMicroop() 1049
|
882 # Source vector copy microop for gather loads 883 emitSveGatherLoadCpySrcVecMicroop()
| 1050 # Source vector copy microop for gather loads 1051 emitSveGatherLoadCpySrcVecMicroop()
|
884
| |
885}};
| 1052}};
|