1// -*- mode:c++ -*- 2
| 1// -*- mode:c++ -*- 2
|
3// Copyright (c) 2012-2013, 2016 ARM Limited
| 3// Copyright (c) 2012-2013, 2016-2018 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: Thomas Grocutt 39// Edmund Grimley Evans 40 41let {{ 42 43 header_output = "" 44 decoder_output = "" 45 exec_output = "" 46 47 fmovImmSCode = vfp64EnabledCheckCode + ''' 48 AA64FpDestP0_uw = bits(imm, 31, 0); 49 AA64FpDestP1_uw = 0; 50 AA64FpDestP2_uw = 0; 51 AA64FpDestP3_uw = 0; 52 ''' 53 fmovImmSIop = InstObjParams("fmov", "FmovImmS", "FpRegImmOp", 54 { "code": fmovImmSCode, 55 "op_class": "FloatMiscOp" }, []) 56 header_output += FpRegImmOpDeclare.subst(fmovImmSIop); 57 decoder_output += FpRegImmOpConstructor.subst(fmovImmSIop); 58 exec_output += BasicExecute.subst(fmovImmSIop); 59 60 fmovImmDCode = vfp64EnabledCheckCode + ''' 61 AA64FpDestP0_uw = bits(imm, 31, 0); 62 AA64FpDestP1_uw = bits(imm, 63, 32); 63 AA64FpDestP2_uw = 0; 64 AA64FpDestP3_uw = 0; 65 ''' 66 fmovImmDIop = InstObjParams("fmov", "FmovImmD", "FpRegImmOp", 67 { "code": fmovImmDCode, 68 "op_class": "FloatMiscOp" }, []) 69 header_output += FpRegImmOpDeclare.subst(fmovImmDIop); 70 decoder_output += AA64FpRegImmOpConstructor.subst(fmovImmDIop); 71 exec_output += BasicExecute.subst(fmovImmDIop); 72 73 fmovRegSCode = vfp64EnabledCheckCode + ''' 74 AA64FpDestP0_uw = AA64FpOp1P0_uw; 75 AA64FpDestP1_uw = 0; 76 AA64FpDestP2_uw = 0; 77 AA64FpDestP3_uw = 0; 78 ''' 79 fmovRegSIop = InstObjParams("fmov", "FmovRegS", "FpRegRegOp", 80 { "code": fmovRegSCode, 81 "op_class": "FloatMiscOp" }, []) 82 header_output += FpRegRegOpDeclare.subst(fmovRegSIop); 83 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegSIop); 84 exec_output += BasicExecute.subst(fmovRegSIop); 85 86 fmovRegDCode = vfp64EnabledCheckCode + ''' 87 AA64FpDestP0_uw = AA64FpOp1P0_uw; 88 AA64FpDestP1_uw = AA64FpOp1P1_uw; 89 AA64FpDestP2_uw = 0; 90 AA64FpDestP3_uw = 0; 91 ''' 92 fmovRegDIop = InstObjParams("fmov", "FmovRegD", "FpRegRegOp", 93 { "code": fmovRegDCode, 94 "op_class": "FloatMiscOp" }, []) 95 header_output += FpRegRegOpDeclare.subst(fmovRegDIop); 96 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegDIop); 97 exec_output += BasicExecute.subst(fmovRegDIop); 98 99 fmovCoreRegWCode = vfp64EnabledCheckCode + ''' 100 AA64FpDestP0_uw = WOp1_uw; 101 AA64FpDestP1_uw = 0; 102 AA64FpDestP2_uw = 0; 103 AA64FpDestP3_uw = 0; 104 ''' 105 fmovCoreRegWIop = InstObjParams("fmov", "FmovCoreRegW", "FpRegRegOp", 106 { "code": fmovCoreRegWCode, 107 "op_class": "FloatMiscOp" }, []) 108 header_output += FpRegRegOpDeclare.subst(fmovCoreRegWIop); 109 decoder_output += AA64FpRegRegOpConstructor.subst(fmovCoreRegWIop); 110 exec_output += BasicExecute.subst(fmovCoreRegWIop); 111 112 fmovCoreRegXCode = vfp64EnabledCheckCode + ''' 113 AA64FpDestP0_uw = XOp1_ud; 114 AA64FpDestP1_uw = XOp1_ud >> 32; 115 AA64FpDestP2_uw = 0; 116 AA64FpDestP3_uw = 0; 117 ''' 118 fmovCoreRegXIop = InstObjParams("fmov", "FmovCoreRegX", "FpRegRegOp", 119 { "code": fmovCoreRegXCode, 120 "op_class": "FloatMiscOp" }, []) 121 header_output += FpRegRegOpDeclare.subst(fmovCoreRegXIop); 122 decoder_output += AA64FpRegRegOpConstructor.subst(fmovCoreRegXIop); 123 exec_output += BasicExecute.subst(fmovCoreRegXIop); 124 125 fmovUCoreRegXCode = vfp64EnabledCheckCode + ''' 126 /* Explicitly merge with previous value */ 127 AA64FpDestP0_uw = AA64FpDestP0_uw; 128 AA64FpDestP1_uw = AA64FpDestP1_uw; 129 AA64FpDestP2_uw = XOp1_ud; 130 AA64FpDestP3_uw = XOp1_ud >> 32;''' 131 fmovUCoreRegXIop = InstObjParams("fmov", "FmovUCoreRegX", "FpRegRegOp", 132 { "code": fmovUCoreRegXCode, 133 "op_class": "FloatMiscOp" }, []) 134 header_output += FpRegRegOpDeclare.subst(fmovUCoreRegXIop); 135 decoder_output += AA64FpRegRegOpConstructor.subst(fmovUCoreRegXIop); 136 exec_output += BasicExecute.subst(fmovUCoreRegXIop); 137 138 fmovRegCoreWCode = vfp64EnabledCheckCode + ''' 139 WDest = AA64FpOp1P0_uw; 140 ''' 141 fmovRegCoreWIop = InstObjParams("fmov", "FmovRegCoreW", "FpRegRegOp", 142 { "code": fmovRegCoreWCode, 143 "op_class": "FloatMiscOp" }, []) 144 header_output += FpRegRegOpDeclare.subst(fmovRegCoreWIop); 145 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegCoreWIop); 146 exec_output += BasicExecute.subst(fmovRegCoreWIop); 147 148 fmovRegCoreXCode = vfp64EnabledCheckCode + ''' 149 XDest = ( ((uint64_t) AA64FpOp1P1_uw) << 32) | AA64FpOp1P0_uw; 150 ''' 151 fmovRegCoreXIop = InstObjParams("fmov", "FmovRegCoreX", "FpRegRegOp", 152 { "code": fmovRegCoreXCode, 153 "op_class": "FloatMiscOp" }, []) 154 header_output += FpRegRegOpDeclare.subst(fmovRegCoreXIop); 155 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegCoreXIop); 156 exec_output += BasicExecute.subst(fmovRegCoreXIop); 157 158 fmovURegCoreXCode = vfp64EnabledCheckCode + ''' 159 XDest = ( ((uint64_t) AA64FpOp1P3_uw) << 32) | AA64FpOp1P2_uw; 160 ''' 161 fmovURegCoreXIop = InstObjParams("fmov", "FmovURegCoreX", "FpRegRegOp", 162 { "code": fmovURegCoreXCode, 163 "op_class": "FloatMiscOp" }, []) 164 header_output += FpRegRegOpDeclare.subst(fmovURegCoreXIop); 165 decoder_output += AA64FpRegRegOpConstructor.subst(fmovURegCoreXIop); 166 exec_output += BasicExecute.subst(fmovURegCoreXIop); 167}}; 168 169let {{ 170 171 header_output = "" 172 decoder_output = "" 173 exec_output = "" 174
| 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: Thomas Grocutt 39// Edmund Grimley Evans 40 41let {{ 42 43 header_output = "" 44 decoder_output = "" 45 exec_output = "" 46 47 fmovImmSCode = vfp64EnabledCheckCode + ''' 48 AA64FpDestP0_uw = bits(imm, 31, 0); 49 AA64FpDestP1_uw = 0; 50 AA64FpDestP2_uw = 0; 51 AA64FpDestP3_uw = 0; 52 ''' 53 fmovImmSIop = InstObjParams("fmov", "FmovImmS", "FpRegImmOp", 54 { "code": fmovImmSCode, 55 "op_class": "FloatMiscOp" }, []) 56 header_output += FpRegImmOpDeclare.subst(fmovImmSIop); 57 decoder_output += FpRegImmOpConstructor.subst(fmovImmSIop); 58 exec_output += BasicExecute.subst(fmovImmSIop); 59 60 fmovImmDCode = vfp64EnabledCheckCode + ''' 61 AA64FpDestP0_uw = bits(imm, 31, 0); 62 AA64FpDestP1_uw = bits(imm, 63, 32); 63 AA64FpDestP2_uw = 0; 64 AA64FpDestP3_uw = 0; 65 ''' 66 fmovImmDIop = InstObjParams("fmov", "FmovImmD", "FpRegImmOp", 67 { "code": fmovImmDCode, 68 "op_class": "FloatMiscOp" }, []) 69 header_output += FpRegImmOpDeclare.subst(fmovImmDIop); 70 decoder_output += AA64FpRegImmOpConstructor.subst(fmovImmDIop); 71 exec_output += BasicExecute.subst(fmovImmDIop); 72 73 fmovRegSCode = vfp64EnabledCheckCode + ''' 74 AA64FpDestP0_uw = AA64FpOp1P0_uw; 75 AA64FpDestP1_uw = 0; 76 AA64FpDestP2_uw = 0; 77 AA64FpDestP3_uw = 0; 78 ''' 79 fmovRegSIop = InstObjParams("fmov", "FmovRegS", "FpRegRegOp", 80 { "code": fmovRegSCode, 81 "op_class": "FloatMiscOp" }, []) 82 header_output += FpRegRegOpDeclare.subst(fmovRegSIop); 83 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegSIop); 84 exec_output += BasicExecute.subst(fmovRegSIop); 85 86 fmovRegDCode = vfp64EnabledCheckCode + ''' 87 AA64FpDestP0_uw = AA64FpOp1P0_uw; 88 AA64FpDestP1_uw = AA64FpOp1P1_uw; 89 AA64FpDestP2_uw = 0; 90 AA64FpDestP3_uw = 0; 91 ''' 92 fmovRegDIop = InstObjParams("fmov", "FmovRegD", "FpRegRegOp", 93 { "code": fmovRegDCode, 94 "op_class": "FloatMiscOp" }, []) 95 header_output += FpRegRegOpDeclare.subst(fmovRegDIop); 96 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegDIop); 97 exec_output += BasicExecute.subst(fmovRegDIop); 98 99 fmovCoreRegWCode = vfp64EnabledCheckCode + ''' 100 AA64FpDestP0_uw = WOp1_uw; 101 AA64FpDestP1_uw = 0; 102 AA64FpDestP2_uw = 0; 103 AA64FpDestP3_uw = 0; 104 ''' 105 fmovCoreRegWIop = InstObjParams("fmov", "FmovCoreRegW", "FpRegRegOp", 106 { "code": fmovCoreRegWCode, 107 "op_class": "FloatMiscOp" }, []) 108 header_output += FpRegRegOpDeclare.subst(fmovCoreRegWIop); 109 decoder_output += AA64FpRegRegOpConstructor.subst(fmovCoreRegWIop); 110 exec_output += BasicExecute.subst(fmovCoreRegWIop); 111 112 fmovCoreRegXCode = vfp64EnabledCheckCode + ''' 113 AA64FpDestP0_uw = XOp1_ud; 114 AA64FpDestP1_uw = XOp1_ud >> 32; 115 AA64FpDestP2_uw = 0; 116 AA64FpDestP3_uw = 0; 117 ''' 118 fmovCoreRegXIop = InstObjParams("fmov", "FmovCoreRegX", "FpRegRegOp", 119 { "code": fmovCoreRegXCode, 120 "op_class": "FloatMiscOp" }, []) 121 header_output += FpRegRegOpDeclare.subst(fmovCoreRegXIop); 122 decoder_output += AA64FpRegRegOpConstructor.subst(fmovCoreRegXIop); 123 exec_output += BasicExecute.subst(fmovCoreRegXIop); 124 125 fmovUCoreRegXCode = vfp64EnabledCheckCode + ''' 126 /* Explicitly merge with previous value */ 127 AA64FpDestP0_uw = AA64FpDestP0_uw; 128 AA64FpDestP1_uw = AA64FpDestP1_uw; 129 AA64FpDestP2_uw = XOp1_ud; 130 AA64FpDestP3_uw = XOp1_ud >> 32;''' 131 fmovUCoreRegXIop = InstObjParams("fmov", "FmovUCoreRegX", "FpRegRegOp", 132 { "code": fmovUCoreRegXCode, 133 "op_class": "FloatMiscOp" }, []) 134 header_output += FpRegRegOpDeclare.subst(fmovUCoreRegXIop); 135 decoder_output += AA64FpRegRegOpConstructor.subst(fmovUCoreRegXIop); 136 exec_output += BasicExecute.subst(fmovUCoreRegXIop); 137 138 fmovRegCoreWCode = vfp64EnabledCheckCode + ''' 139 WDest = AA64FpOp1P0_uw; 140 ''' 141 fmovRegCoreWIop = InstObjParams("fmov", "FmovRegCoreW", "FpRegRegOp", 142 { "code": fmovRegCoreWCode, 143 "op_class": "FloatMiscOp" }, []) 144 header_output += FpRegRegOpDeclare.subst(fmovRegCoreWIop); 145 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegCoreWIop); 146 exec_output += BasicExecute.subst(fmovRegCoreWIop); 147 148 fmovRegCoreXCode = vfp64EnabledCheckCode + ''' 149 XDest = ( ((uint64_t) AA64FpOp1P1_uw) << 32) | AA64FpOp1P0_uw; 150 ''' 151 fmovRegCoreXIop = InstObjParams("fmov", "FmovRegCoreX", "FpRegRegOp", 152 { "code": fmovRegCoreXCode, 153 "op_class": "FloatMiscOp" }, []) 154 header_output += FpRegRegOpDeclare.subst(fmovRegCoreXIop); 155 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegCoreXIop); 156 exec_output += BasicExecute.subst(fmovRegCoreXIop); 157 158 fmovURegCoreXCode = vfp64EnabledCheckCode + ''' 159 XDest = ( ((uint64_t) AA64FpOp1P3_uw) << 32) | AA64FpOp1P2_uw; 160 ''' 161 fmovURegCoreXIop = InstObjParams("fmov", "FmovURegCoreX", "FpRegRegOp", 162 { "code": fmovURegCoreXCode, 163 "op_class": "FloatMiscOp" }, []) 164 header_output += FpRegRegOpDeclare.subst(fmovURegCoreXIop); 165 decoder_output += AA64FpRegRegOpConstructor.subst(fmovURegCoreXIop); 166 exec_output += BasicExecute.subst(fmovURegCoreXIop); 167}}; 168 169let {{ 170 171 header_output = "" 172 decoder_output = "" 173 exec_output = "" 174
|
| 175 halfIntConvCode = vfp64EnabledCheckCode + ''' 176 FPSCR fpscr = (FPSCR) FpscrExc; 177 uint16_t cOp1 = AA64FpOp1P0_uw; 178 uint16_t cDest = %(op)s; 179 AA64FpDestP0_uw = cDest; 180 AA64FpDestP1_uw = 0; 181 AA64FpDestP2_uw = 0; 182 AA64FpDestP3_uw = 0; 183 FpscrExc = fpscr; 184 ''' 185 186 halfIntConvCode2 = vfp64EnabledCheckCode + ''' 187 FPSCR fpscr = (FPSCR) FpscrExc; 188 uint16_t cOp1 = AA64FpOp1P0_uw; 189 uint16_t cOp2 = AA64FpOp2P0_uw; 190 uint16_t cDest = %(op)s; 191 AA64FpDestP0_uw = cDest; 192 AA64FpDestP1_uw = 0; 193 AA64FpDestP2_uw = 0; 194 AA64FpDestP3_uw = 0; 195 FpscrExc = fpscr; 196 ''' 197 198 halfBinOp = "binaryOp(fpscr, AA64FpOp1P0, AA64FpOp2P0," + \ 199 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)" 200 halfUnaryOp = "unaryOp(fpscr, AA64FpOp1P0," + \ 201 "%(func)s, fpscr.fz, fpscr.rMode)" 202
|
175 singleIntConvCode = vfp64EnabledCheckCode + ''' 176 FPSCR fpscr = (FPSCR) FpscrExc; 177 uint32_t cOp1 = AA64FpOp1P0_uw; 178 uint32_t cDest = %(op)s; 179 AA64FpDestP0_uw = cDest; 180 AA64FpDestP1_uw = 0; 181 AA64FpDestP2_uw = 0; 182 AA64FpDestP3_uw = 0; 183 FpscrExc = fpscr; 184 ''' 185 186 singleIntConvCode2 = vfp64EnabledCheckCode + ''' 187 FPSCR fpscr = (FPSCR) FpscrExc; 188 uint32_t cOp1 = AA64FpOp1P0_uw; 189 uint32_t cOp2 = AA64FpOp2P0_uw; 190 uint32_t cDest = %(op)s; 191 AA64FpDestP0_uw = cDest; 192 AA64FpDestP1_uw = 0; 193 AA64FpDestP2_uw = 0; 194 AA64FpDestP3_uw = 0; 195 FpscrExc = fpscr; 196 ''' 197 198 singleBinOp = "binaryOp(fpscr, AA64FpOp1P0, AA64FpOp2P0," + \ 199 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)" 200 singleUnaryOp = "unaryOp(fpscr, AA64FpOp1P0, %(func)s, fpscr.fz, fpscr.rMode)" 201 202 doubleIntConvCode = vfp64EnabledCheckCode + ''' 203 FPSCR fpscr = (FPSCR) FpscrExc; 204 uint64_t cOp1 = ((uint64_t) AA64FpOp1P1_uw) << 32 | AA64FpOp1P0_uw; 205 uint64_t cDest = %(op)s; 206 AA64FpDestP0_uw = cDest & 0xFFFFFFFF; 207 AA64FpDestP1_uw = cDest >> 32; 208 AA64FpDestP2_uw = 0; 209 AA64FpDestP3_uw = 0; 210 FpscrExc = fpscr; 211 ''' 212 213 doubleIntConvCode2 = vfp64EnabledCheckCode + ''' 214 FPSCR fpscr = (FPSCR) FpscrExc; 215 uint64_t cOp1 = ((uint64_t) AA64FpOp1P1_uw) << 32 | AA64FpOp1P0_uw; 216 uint64_t cOp2 = ((uint64_t) AA64FpOp2P1_uw) << 32 | AA64FpOp2P0_uw; 217 uint64_t cDest = %(op)s; 218 AA64FpDestP0_uw = cDest & 0xFFFFFFFF; 219 AA64FpDestP1_uw = cDest >> 32; 220 AA64FpDestP2_uw = 0; 221 AA64FpDestP3_uw = 0; 222 FpscrExc = fpscr; 223 ''' 224 225 doubleBinOp = ''' 226 binaryOp(fpscr, dbl(AA64FpOp1P0_uw, AA64FpOp1P1_uw), 227 dbl(AA64FpOp2P0_uw, AA64FpOp2P1_uw), 228 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode); 229 ''' 230 doubleUnaryOp = ''' 231 unaryOp(fpscr, dbl(AA64FpOp1P0_uw, AA64FpOp1P1_uw), %(func)s, 232 fpscr.fz, fpscr.rMode) 233 ''' 234
| 203 singleIntConvCode = vfp64EnabledCheckCode + ''' 204 FPSCR fpscr = (FPSCR) FpscrExc; 205 uint32_t cOp1 = AA64FpOp1P0_uw; 206 uint32_t cDest = %(op)s; 207 AA64FpDestP0_uw = cDest; 208 AA64FpDestP1_uw = 0; 209 AA64FpDestP2_uw = 0; 210 AA64FpDestP3_uw = 0; 211 FpscrExc = fpscr; 212 ''' 213 214 singleIntConvCode2 = vfp64EnabledCheckCode + ''' 215 FPSCR fpscr = (FPSCR) FpscrExc; 216 uint32_t cOp1 = AA64FpOp1P0_uw; 217 uint32_t cOp2 = AA64FpOp2P0_uw; 218 uint32_t cDest = %(op)s; 219 AA64FpDestP0_uw = cDest; 220 AA64FpDestP1_uw = 0; 221 AA64FpDestP2_uw = 0; 222 AA64FpDestP3_uw = 0; 223 FpscrExc = fpscr; 224 ''' 225 226 singleBinOp = "binaryOp(fpscr, AA64FpOp1P0, AA64FpOp2P0," + \ 227 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)" 228 singleUnaryOp = "unaryOp(fpscr, AA64FpOp1P0, %(func)s, fpscr.fz, fpscr.rMode)" 229 230 doubleIntConvCode = vfp64EnabledCheckCode + ''' 231 FPSCR fpscr = (FPSCR) FpscrExc; 232 uint64_t cOp1 = ((uint64_t) AA64FpOp1P1_uw) << 32 | AA64FpOp1P0_uw; 233 uint64_t cDest = %(op)s; 234 AA64FpDestP0_uw = cDest & 0xFFFFFFFF; 235 AA64FpDestP1_uw = cDest >> 32; 236 AA64FpDestP2_uw = 0; 237 AA64FpDestP3_uw = 0; 238 FpscrExc = fpscr; 239 ''' 240 241 doubleIntConvCode2 = vfp64EnabledCheckCode + ''' 242 FPSCR fpscr = (FPSCR) FpscrExc; 243 uint64_t cOp1 = ((uint64_t) AA64FpOp1P1_uw) << 32 | AA64FpOp1P0_uw; 244 uint64_t cOp2 = ((uint64_t) AA64FpOp2P1_uw) << 32 | AA64FpOp2P0_uw; 245 uint64_t cDest = %(op)s; 246 AA64FpDestP0_uw = cDest & 0xFFFFFFFF; 247 AA64FpDestP1_uw = cDest >> 32; 248 AA64FpDestP2_uw = 0; 249 AA64FpDestP3_uw = 0; 250 FpscrExc = fpscr; 251 ''' 252 253 doubleBinOp = ''' 254 binaryOp(fpscr, dbl(AA64FpOp1P0_uw, AA64FpOp1P1_uw), 255 dbl(AA64FpOp2P0_uw, AA64FpOp2P1_uw), 256 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode); 257 ''' 258 doubleUnaryOp = ''' 259 unaryOp(fpscr, dbl(AA64FpOp1P0_uw, AA64FpOp1P1_uw), %(func)s, 260 fpscr.fz, fpscr.rMode) 261 ''' 262
|
235 def buildTernaryFpOp(name, opClass, sOp, dOp):
| 263 def buildTernaryFpOp(name, opClass, hOp, sOp, dOp):
|
236 global header_output, decoder_output, exec_output
| 264 global header_output, decoder_output, exec_output
|
237 for isDouble in True, False:
| 265 for suffix in "D", "S", "H":
|
238 code = vfp64EnabledCheckCode + ''' 239 FPSCR fpscr = (FPSCR) FpscrExc; 240 '''
| 266 code = vfp64EnabledCheckCode + ''' 267 FPSCR fpscr = (FPSCR) FpscrExc; 268 '''
|
241 if isDouble:
| 269 if suffix == "H":
|
242 code += '''
| 270 code += '''
|
243 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 244 uint64_t cOp2 = AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32; 245 uint64_t cOp3 = AA64FpOp3P0_uw | (uint64_t)AA64FpOp3P1_uw << 32; 246 uint64_t cDest; 247 ''' "cDest = " + dOp + ";" + '''
| 271 uint16_t cOp1 = AA64FpOp1P0_uw; 272 uint16_t cOp2 = AA64FpOp2P0_uw; 273 uint16_t cOp3 = AA64FpOp3P0_uw; 274 uint16_t cDest; 275 ''' "cDest = " + hOp + ";" + '''
|
248 AA64FpDestP0_uw = cDest;
| 276 AA64FpDestP0_uw = cDest;
|
249 AA64FpDestP1_uw = cDest >> 32;
| 277 AA64FpDestP1_uw = 0;
|
250 '''
| 278 '''
|
251 else:
| 279 elif suffix == "S":
|
252 code += ''' 253 uint32_t cOp1 = AA64FpOp1P0_uw; 254 uint32_t cOp2 = AA64FpOp2P0_uw; 255 uint32_t cOp3 = AA64FpOp3P0_uw; 256 uint32_t cDest; 257 ''' "cDest = " + sOp + ";" + ''' 258 AA64FpDestP0_uw = cDest; 259 AA64FpDestP1_uw = 0; 260 '''
| 280 code += ''' 281 uint32_t cOp1 = AA64FpOp1P0_uw; 282 uint32_t cOp2 = AA64FpOp2P0_uw; 283 uint32_t cOp3 = AA64FpOp3P0_uw; 284 uint32_t cDest; 285 ''' "cDest = " + sOp + ";" + ''' 286 AA64FpDestP0_uw = cDest; 287 AA64FpDestP1_uw = 0; 288 '''
|
| 289 elif suffix == "D": 290 code += ''' 291 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 292 uint64_t cOp2 = AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32; 293 uint64_t cOp3 = AA64FpOp3P0_uw | (uint64_t)AA64FpOp3P1_uw << 32; 294 uint64_t cDest; 295 ''' "cDest = " + dOp + ";" + ''' 296 AA64FpDestP0_uw = cDest; 297 AA64FpDestP1_uw = cDest >> 32; 298 '''
|
261 code += ''' 262 AA64FpDestP2_uw = 0; 263 AA64FpDestP3_uw = 0; 264 FpscrExc = fpscr; 265 ''' 266
| 299 code += ''' 300 AA64FpDestP2_uw = 0; 301 AA64FpDestP3_uw = 0; 302 FpscrExc = fpscr; 303 ''' 304
|
267 iop = InstObjParams(name.lower(), name + ("D" if isDouble else "S"),
| 305 iop = InstObjParams(name.lower(), name + suffix,
|
268 "FpRegRegRegRegOp", 269 { "code": code, "op_class": opClass }, []) 270 271 header_output += AA64FpRegRegRegRegOpDeclare.subst(iop) 272 decoder_output += AA64FpRegRegRegRegOpConstructor.subst(iop) 273 exec_output += BasicExecute.subst(iop) 274 275 buildTernaryFpOp("FMAdd", "FloatMultAccOp",
| 306 "FpRegRegRegRegOp", 307 { "code": code, "op_class": opClass }, []) 308 309 header_output += AA64FpRegRegRegRegOpDeclare.subst(iop) 310 decoder_output += AA64FpRegRegRegRegOpConstructor.subst(iop) 311 exec_output += BasicExecute.subst(iop) 312 313 buildTernaryFpOp("FMAdd", "FloatMultAccOp",
|
| 314 "fplibMulAdd<uint16_t>(cOp3, cOp1, cOp2, fpscr)",
|
276 "fplibMulAdd<uint32_t>(cOp3, cOp1, cOp2, fpscr)", 277 "fplibMulAdd<uint64_t>(cOp3, cOp1, cOp2, fpscr)" ) 278 buildTernaryFpOp("FMSub", "FloatMultAccOp",
| 315 "fplibMulAdd<uint32_t>(cOp3, cOp1, cOp2, fpscr)", 316 "fplibMulAdd<uint64_t>(cOp3, cOp1, cOp2, fpscr)" ) 317 buildTernaryFpOp("FMSub", "FloatMultAccOp",
|
279 "fplibMulAdd<uint32_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)", 280 "fplibMulAdd<uint64_t>(cOp3, fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" )
| 318 "fplibMulAdd<uint16_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)", 319 "fplibMulAdd<uint32_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)", 320 "fplibMulAdd<uint64_t>(cOp3, fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" )
|
281 buildTernaryFpOp("FNMAdd", "FloatMultAccOp",
| 321 buildTernaryFpOp("FNMAdd", "FloatMultAccOp",
|
282 "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), fplibNeg<uint32_t>(cOp1), cOp2, fpscr)", 283 "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" )
| 322 "fplibMulAdd<uint16_t>(fplibNeg<uint16_t>(cOp3), " + 323 "fplibNeg<uint16_t>(cOp1), cOp2, fpscr)", 324 "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), " + 325 "fplibNeg<uint32_t>(cOp1), cOp2, fpscr)", 326 "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), " + 327 "fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" )
|
284 buildTernaryFpOp("FNMSub", "FloatMultAccOp",
| 328 buildTernaryFpOp("FNMSub", "FloatMultAccOp",
|
285 "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)", 286 "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), cOp1, cOp2, fpscr)" )
| 329 "fplibMulAdd<uint16_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)", 330 "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)", 331 "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), cOp1, cOp2, fpscr)" )
|
287
| 332
|
288 def buildBinFpOp(name, Name, base, opClass, singleOp, doubleOp):
| 333 def buildBinFpOp(name, Name, base, opClass, halfOp, singleOp, doubleOp):
|
289 global header_output, decoder_output, exec_output 290
| 334 global header_output, decoder_output, exec_output 335
|
| 336 code = halfIntConvCode2 % { "op": halfOp } 337 hIop = InstObjParams(name, Name + "H", base, 338 { "code": code, 339 "op_class": opClass }, []) 340
|
291 code = singleIntConvCode2 % { "op": singleOp } 292 sIop = InstObjParams(name, Name + "S", base, 293 { "code": code, 294 "op_class": opClass }, []) 295 296 code = doubleIntConvCode2 % { "op": doubleOp } 297 dIop = InstObjParams(name, Name + "D", base, 298 { "code": code, 299 "op_class": opClass }, []) 300 301 declareTempl = eval( base + "Declare"); 302 constructorTempl = eval("AA64" + base + "Constructor"); 303
| 341 code = singleIntConvCode2 % { "op": singleOp } 342 sIop = InstObjParams(name, Name + "S", base, 343 { "code": code, 344 "op_class": opClass }, []) 345 346 code = doubleIntConvCode2 % { "op": doubleOp } 347 dIop = InstObjParams(name, Name + "D", base, 348 { "code": code, 349 "op_class": opClass }, []) 350 351 declareTempl = eval( base + "Declare"); 352 constructorTempl = eval("AA64" + base + "Constructor"); 353
|
304 for iop in sIop, dIop:
| 354 for iop in hIop, sIop, dIop:
|
305 header_output += declareTempl.subst(iop) 306 decoder_output += constructorTempl.subst(iop) 307 exec_output += BasicExecute.subst(iop) 308 309 buildBinFpOp("fadd", "FAdd", "FpRegRegRegOp", "FloatAddOp",
| 355 header_output += declareTempl.subst(iop) 356 decoder_output += constructorTempl.subst(iop) 357 exec_output += BasicExecute.subst(iop) 358 359 buildBinFpOp("fadd", "FAdd", "FpRegRegRegOp", "FloatAddOp",
|
| 360 "fplibAdd<uint16_t>(cOp1, cOp2, fpscr)",
|
310 "fplibAdd<uint32_t>(cOp1, cOp2, fpscr)", 311 "fplibAdd<uint64_t>(cOp1, cOp2, fpscr)") 312 buildBinFpOp("fsub", "FSub", "FpRegRegRegOp", "FloatAddOp",
| 361 "fplibAdd<uint32_t>(cOp1, cOp2, fpscr)", 362 "fplibAdd<uint64_t>(cOp1, cOp2, fpscr)") 363 buildBinFpOp("fsub", "FSub", "FpRegRegRegOp", "FloatAddOp",
|
| 364 "fplibSub<uint16_t>(cOp1, cOp2, fpscr)",
|
313 "fplibSub<uint32_t>(cOp1, cOp2, fpscr)", 314 "fplibSub<uint64_t>(cOp1, cOp2, fpscr)") 315 buildBinFpOp("fdiv", "FDiv", "FpRegRegRegOp", "FloatDivOp",
| 365 "fplibSub<uint32_t>(cOp1, cOp2, fpscr)", 366 "fplibSub<uint64_t>(cOp1, cOp2, fpscr)") 367 buildBinFpOp("fdiv", "FDiv", "FpRegRegRegOp", "FloatDivOp",
|
| 368 "fplibDiv<uint16_t>(cOp1, cOp2, fpscr)",
|
316 "fplibDiv<uint32_t>(cOp1, cOp2, fpscr)", 317 "fplibDiv<uint64_t>(cOp1, cOp2, fpscr)") 318 buildBinFpOp("fmul", "FMul", "FpRegRegRegOp", "FloatMultOp",
| 369 "fplibDiv<uint32_t>(cOp1, cOp2, fpscr)", 370 "fplibDiv<uint64_t>(cOp1, cOp2, fpscr)") 371 buildBinFpOp("fmul", "FMul", "FpRegRegRegOp", "FloatMultOp",
|
| 372 "fplibMul<uint16_t>(cOp1, cOp2, fpscr)",
|
319 "fplibMul<uint32_t>(cOp1, cOp2, fpscr)", 320 "fplibMul<uint64_t>(cOp1, cOp2, fpscr)") 321 buildBinFpOp("fnmul", "FNMul", "FpRegRegRegOp", "FloatMultOp",
| 373 "fplibMul<uint32_t>(cOp1, cOp2, fpscr)", 374 "fplibMul<uint64_t>(cOp1, cOp2, fpscr)") 375 buildBinFpOp("fnmul", "FNMul", "FpRegRegRegOp", "FloatMultOp",
|
| 376 "fplibNeg<uint16_t>(fplibMul<uint32_t>(cOp1, cOp2, fpscr))",
|
322 "fplibNeg<uint32_t>(fplibMul<uint32_t>(cOp1, cOp2, fpscr))", 323 "fplibNeg<uint64_t>(fplibMul<uint64_t>(cOp1, cOp2, fpscr))") 324 buildBinFpOp("fmin", "FMin", "FpRegRegRegOp", "FloatCmpOp",
| 377 "fplibNeg<uint32_t>(fplibMul<uint32_t>(cOp1, cOp2, fpscr))", 378 "fplibNeg<uint64_t>(fplibMul<uint64_t>(cOp1, cOp2, fpscr))") 379 buildBinFpOp("fmin", "FMin", "FpRegRegRegOp", "FloatCmpOp",
|
| 380 "fplibMin<uint16_t>(cOp1, cOp2, fpscr)",
|
325 "fplibMin<uint32_t>(cOp1, cOp2, fpscr)", 326 "fplibMin<uint64_t>(cOp1, cOp2, fpscr)") 327 buildBinFpOp("fmax", "FMax", "FpRegRegRegOp", "FloatCmpOp",
| 381 "fplibMin<uint32_t>(cOp1, cOp2, fpscr)", 382 "fplibMin<uint64_t>(cOp1, cOp2, fpscr)") 383 buildBinFpOp("fmax", "FMax", "FpRegRegRegOp", "FloatCmpOp",
|
| 384 "fplibMax<uint16_t>(cOp1, cOp2, fpscr)",
|
328 "fplibMax<uint32_t>(cOp1, cOp2, fpscr)", 329 "fplibMax<uint64_t>(cOp1, cOp2, fpscr)") 330 buildBinFpOp("fminnm", "FMinNM", "FpRegRegRegOp", "FloatCmpOp",
| 385 "fplibMax<uint32_t>(cOp1, cOp2, fpscr)", 386 "fplibMax<uint64_t>(cOp1, cOp2, fpscr)") 387 buildBinFpOp("fminnm", "FMinNM", "FpRegRegRegOp", "FloatCmpOp",
|
| 388 "fplibMinNum<uint16_t>(cOp1, cOp2, fpscr)",
|
331 "fplibMinNum<uint32_t>(cOp1, cOp2, fpscr)", 332 "fplibMinNum<uint64_t>(cOp1, cOp2, fpscr)") 333 buildBinFpOp("fmaxnm", "FMaxNM", "FpRegRegRegOp", "FloatCmpOp",
| 389 "fplibMinNum<uint32_t>(cOp1, cOp2, fpscr)", 390 "fplibMinNum<uint64_t>(cOp1, cOp2, fpscr)") 391 buildBinFpOp("fmaxnm", "FMaxNM", "FpRegRegRegOp", "FloatCmpOp",
|
| 392 "fplibMaxNum<uint16_t>(cOp1, cOp2, fpscr)",
|
334 "fplibMaxNum<uint32_t>(cOp1, cOp2, fpscr)", 335 "fplibMaxNum<uint64_t>(cOp1, cOp2, fpscr)") 336
| 393 "fplibMaxNum<uint32_t>(cOp1, cOp2, fpscr)", 394 "fplibMaxNum<uint64_t>(cOp1, cOp2, fpscr)") 395
|
337 def buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None):
| 396 def buildUnaryFpOp(name, Name, base, opClass, 397 halfOp, singleOp, doubleOp = None):
|
338 if doubleOp is None: 339 doubleOp = singleOp 340 global header_output, decoder_output, exec_output 341
| 398 if doubleOp is None: 399 doubleOp = singleOp 400 global header_output, decoder_output, exec_output 401
|
| 402 code = halfIntConvCode % { "op": halfOp } 403 hIop = InstObjParams(name, Name + "H", base, 404 { "code": code, 405 "op_class": opClass }, [])
|
342 code = singleIntConvCode % { "op": singleOp } 343 sIop = InstObjParams(name, Name + "S", base, 344 { "code": code, 345 "op_class": opClass }, []) 346 code = doubleIntConvCode % { "op": doubleOp } 347 dIop = InstObjParams(name, Name + "D", base, 348 { "code": code, 349 "op_class": opClass }, []) 350 351 declareTempl = eval( base + "Declare"); 352 constructorTempl = eval("AA64" + base + "Constructor"); 353
| 406 code = singleIntConvCode % { "op": singleOp } 407 sIop = InstObjParams(name, Name + "S", base, 408 { "code": code, 409 "op_class": opClass }, []) 410 code = doubleIntConvCode % { "op": doubleOp } 411 dIop = InstObjParams(name, Name + "D", base, 412 { "code": code, 413 "op_class": opClass }, []) 414 415 declareTempl = eval( base + "Declare"); 416 constructorTempl = eval("AA64" + base + "Constructor"); 417
|
354 for iop in sIop, dIop:
| 418 for iop in hIop, sIop, dIop:
|
355 header_output += declareTempl.subst(iop) 356 decoder_output += constructorTempl.subst(iop) 357 exec_output += BasicExecute.subst(iop) 358 359 buildUnaryFpOp("fsqrt", "FSqrt", "FpRegRegOp", "FloatSqrtOp",
| 419 header_output += declareTempl.subst(iop) 420 decoder_output += constructorTempl.subst(iop) 421 exec_output += BasicExecute.subst(iop) 422 423 buildUnaryFpOp("fsqrt", "FSqrt", "FpRegRegOp", "FloatSqrtOp",
|
360 "fplibSqrt<uint32_t>(cOp1, fpscr)", "fplibSqrt<uint64_t>(cOp1, fpscr)")
| 424 "fplibSqrt<uint16_t>(cOp1, fpscr)", 425 "fplibSqrt<uint32_t>(cOp1, fpscr)", 426 "fplibSqrt<uint64_t>(cOp1, fpscr)")
|
361
| 427
|
362 def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp,
| 428 def buildSimpleUnaryFpOp(name, Name, base, opClass, halfOp, singleOp,
|
363 doubleOp = None, isIntConv = True): 364 if doubleOp is None: 365 doubleOp = singleOp 366 global header_output, decoder_output, exec_output 367 368 if isIntConv:
| 429 doubleOp = None, isIntConv = True): 430 if doubleOp is None: 431 doubleOp = singleOp 432 global header_output, decoder_output, exec_output 433 434 if isIntConv:
|
| 435 hCode = halfIntConvCode
|
369 sCode = singleIntConvCode 370 dCode = doubleIntConvCode 371 else:
| 436 sCode = singleIntConvCode 437 dCode = doubleIntConvCode 438 else:
|
| 439 hCode = halfCode
|
372 sCode = singleCode 373 dCode = doubleCode 374
| 440 sCode = singleCode 441 dCode = doubleCode 442
|
375 for code, op, suffix in [[sCode, singleOp, "S"],
| 443 for code, op, suffix in [[hCode, halfOp, "H"], 444 [sCode, singleOp, "S"],
|
376 [dCode, doubleOp, "D"]]: 377 iop = InstObjParams(name, Name + suffix, base, 378 { "code": code % { "op": op }, 379 "op_class": opClass }, []) 380 381 declareTempl = eval( base + "Declare"); 382 constructorTempl = eval("AA64" + base + "Constructor"); 383 384 header_output += declareTempl.subst(iop) 385 decoder_output += constructorTempl.subst(iop) 386 exec_output += BasicExecute.subst(iop) 387 388 buildSimpleUnaryFpOp("fneg", "FNeg", "FpRegRegOp", "FloatMiscOp",
| 445 [dCode, doubleOp, "D"]]: 446 iop = InstObjParams(name, Name + suffix, base, 447 { "code": code % { "op": op }, 448 "op_class": opClass }, []) 449 450 declareTempl = eval( base + "Declare"); 451 constructorTempl = eval("AA64" + base + "Constructor"); 452 453 header_output += declareTempl.subst(iop) 454 decoder_output += constructorTempl.subst(iop) 455 exec_output += BasicExecute.subst(iop) 456 457 buildSimpleUnaryFpOp("fneg", "FNeg", "FpRegRegOp", "FloatMiscOp",
|
389 "fplibNeg<uint32_t>(cOp1)", "fplibNeg<uint64_t>(cOp1)")
| 458 "fplibNeg<uint16_t>(cOp1)", 459 "fplibNeg<uint32_t>(cOp1)", 460 "fplibNeg<uint64_t>(cOp1)")
|
390 buildSimpleUnaryFpOp("fabs", "FAbs", "FpRegRegOp", "FloatMiscOp",
| 461 buildSimpleUnaryFpOp("fabs", "FAbs", "FpRegRegOp", "FloatMiscOp",
|
391 "fplibAbs<uint32_t>(cOp1)", "fplibAbs<uint64_t>(cOp1)")
| 462 "fplibAbs<uint16_t>(cOp1)", 463 "fplibAbs<uint32_t>(cOp1)", 464 "fplibAbs<uint64_t>(cOp1)")
|
392 buildSimpleUnaryFpOp("frintn", "FRIntN", "FpRegRegOp", "FloatMiscOp",
| 465 buildSimpleUnaryFpOp("frintn", "FRIntN", "FpRegRegOp", "FloatMiscOp",
|
393 "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)", 394 "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)")
| 466 "fplibRoundInt<uint16_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)", 467 "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)", 468 "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)")
|
395 buildSimpleUnaryFpOp("frintp", "FRIntP", "FpRegRegOp", "FloatMiscOp",
| 469 buildSimpleUnaryFpOp("frintp", "FRIntP", "FpRegRegOp", "FloatMiscOp",
|
396 "fplibRoundInt<uint32_t>(cOp1, FPRounding_POSINF, false, fpscr)", 397 "fplibRoundInt<uint64_t>(cOp1, FPRounding_POSINF, false, fpscr)")
| 470 "fplibRoundInt<uint16_t>(cOp1, FPRounding_POSINF, false, fpscr)", 471 "fplibRoundInt<uint32_t>(cOp1, FPRounding_POSINF, false, fpscr)", 472 "fplibRoundInt<uint64_t>(cOp1, FPRounding_POSINF, false, fpscr)")
|
398 buildSimpleUnaryFpOp("frintm", "FRIntM", "FpRegRegOp", "FloatMiscOp",
| 473 buildSimpleUnaryFpOp("frintm", "FRIntM", "FpRegRegOp", "FloatMiscOp",
|
399 "fplibRoundInt<uint32_t>(cOp1, FPRounding_NEGINF, false, fpscr)", 400 "fplibRoundInt<uint64_t>(cOp1, FPRounding_NEGINF, false, fpscr)")
| 474 "fplibRoundInt<uint16_t>(cOp1, FPRounding_NEGINF, false, fpscr)", 475 "fplibRoundInt<uint32_t>(cOp1, FPRounding_NEGINF, false, fpscr)", 476 "fplibRoundInt<uint64_t>(cOp1, FPRounding_NEGINF, false, fpscr)")
|
401 buildSimpleUnaryFpOp("frintz", "FRIntZ", "FpRegRegOp", "FloatMiscOp",
| 477 buildSimpleUnaryFpOp("frintz", "FRIntZ", "FpRegRegOp", "FloatMiscOp",
|
402 "fplibRoundInt<uint32_t>(cOp1, FPRounding_ZERO, false, fpscr)", 403 "fplibRoundInt<uint64_t>(cOp1, FPRounding_ZERO, false, fpscr)")
| 478 "fplibRoundInt<uint16_t>(cOp1, FPRounding_ZERO, false, fpscr)", 479 "fplibRoundInt<uint32_t>(cOp1, FPRounding_ZERO, false, fpscr)", 480 "fplibRoundInt<uint64_t>(cOp1, FPRounding_ZERO, false, fpscr)")
|
404 buildSimpleUnaryFpOp("frinta", "FRIntA", "FpRegRegOp", "FloatMiscOp",
| 481 buildSimpleUnaryFpOp("frinta", "FRIntA", "FpRegRegOp", "FloatMiscOp",
|
405 "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)", 406 "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)")
| 482 "fplibRoundInt<uint16_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)", 483 "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)", 484 "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)")
|
407 buildSimpleUnaryFpOp("frinti", "FRIntI", "FpRegRegOp", "FloatMiscOp",
| 485 buildSimpleUnaryFpOp("frinti", "FRIntI", "FpRegRegOp", "FloatMiscOp",
|
408 "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), false, fpscr)", 409 "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), false, fpscr)")
| 486 "fplibRoundInt<uint16_t>(cOp1, FPCRRounding(fpscr), false, fpscr)", 487 "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), false, fpscr)", 488 "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), false, fpscr)")
|
410 buildSimpleUnaryFpOp("frintx", "FRIntX", "FpRegRegOp", "FloatMiscOp",
| 489 buildSimpleUnaryFpOp("frintx", "FRIntX", "FpRegRegOp", "FloatMiscOp",
|
411 "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), true, fpscr)", 412 "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), true, fpscr)")
| 490 "fplibRoundInt<uint16_t>(cOp1, FPCRRounding(fpscr), true, fpscr)", 491 "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), true, fpscr)", 492 "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), true, fpscr)")
|
413}}; 414 415let {{ 416 417 header_output = "" 418 decoder_output = "" 419 exec_output = "" 420 421 # Creates the integer to floating point instructions, including variants for 422 # signed/unsigned, float/double, etc 423 for regL, regOpL, width in [["W", "w", 32], 424 ["X", "d", 64]]: 425 for isDouble in True, False: 426 for us, usCode in [["U", "uint%d_t cSrc = %sOp1_u%s;" %(width, regL, regOpL)], 427 ["S", "int%d_t cSrc = %sOp1_u%s;" %(width, regL, regOpL)]]: 428 fcvtIntFpDCode = vfp64EnabledCheckCode + ''' 429 FPSCR fpscr = (FPSCR) FpscrExc; 430 %s 431 ''' %(usCode) 432 433 if isDouble: 434 fcvtIntFpDCode += ''' 435 uint64_t cDest = fplibFixedToFP<uint64_t>(cSrc, 0, 436 %s, FPCRRounding(fpscr), fpscr); 437 AA64FpDestP0_uw = cDest; 438 AA64FpDestP1_uw = cDest >> 32; 439 ''' % ("true" if us == "U" else "false") 440 else: 441 fcvtIntFpDCode += ''' 442 uint32_t cDest = fplibFixedToFP<uint32_t>(cSrc, 0, 443 %s, FPCRRounding(fpscr), fpscr); 444 AA64FpDestP0_uw = cDest; 445 AA64FpDestP1_uw = 0; 446 ''' % ("true" if us == "U" else "false") 447 fcvtIntFpDCode += ''' 448 AA64FpDestP2_uw = 0; 449 AA64FpDestP3_uw = 0; 450 FpscrExc = fpscr; 451 ''' 452 453 instName = "Fcvt%s%sIntFp%s" %(regL, us, "D" if isDouble else "S") 454 mnem = "%scvtf" %(us.lower()) 455 fcvtIntFpDIop = InstObjParams(mnem, instName, "FpRegRegOp", 456 { "code": fcvtIntFpDCode, 457 "op_class": "FloatCvtOp" }, []) 458 header_output += FpRegRegOpDeclare.subst(fcvtIntFpDIop); 459 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtIntFpDIop); 460 exec_output += BasicExecute.subst(fcvtIntFpDIop); 461 462 # Generates the floating point to integer conversion instructions in various 463 # variants, eg signed/unsigned 464 def buildFpCvtIntOp(isDouble, isSigned, isXReg): 465 global header_output, decoder_output, exec_output 466 467 for rmode, roundingMode in [["N", "FPRounding_TIEEVEN"], 468 ["P", "FPRounding_POSINF"], 469 ["M", "FPRounding_NEGINF"], 470 ["Z", "FPRounding_ZERO"], 471 ["A", "FPRounding_TIEAWAY"]]: 472 fcvtFpIntCode = vfp64EnabledCheckCode + ''' 473 FPSCR fpscr = (FPSCR) FpscrExc;''' 474 if isDouble: 475 fcvtFpIntCode += ''' 476 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 477 ''' 478 else: 479 fcvtFpIntCode += "uint32_t cOp1 = AA64FpOp1P0_uw;" 480 481 fcvtFpIntCode += ''' 482 %sDest = fplibFPToFixed<uint%s_t, uint%s_t>(cOp1, 0, %s, %s, fpscr); 483 FpscrExc = fpscr; 484 ''' %("X" if isXReg else "W", 485 "64" if isDouble else "32", 486 "64" if isXReg else "32", 487 "false" if isSigned else "true", 488 roundingMode) 489 490 instName = "FcvtFp%sInt%s%s%s" %("S" if isSigned else "U", 491 "X" if isXReg else "W", 492 "D" if isDouble else "S", rmode) 493 mnem = "fcvt%s%s" %(rmode, "s" if isSigned else "u") 494 fcvtFpIntIop = InstObjParams(mnem, instName, "FpRegRegOp", 495 { "code": fcvtFpIntCode, 496 "op_class": "FloatCvtOp" }, []) 497 header_output += FpRegRegOpDeclare.subst(fcvtFpIntIop); 498 decoder_output += FpRegRegOpConstructor.subst(fcvtFpIntIop); 499 exec_output += BasicExecute.subst(fcvtFpIntIop); 500 501 # Now actually do the building with the different variants 502 for isDouble in True, False: 503 for isSigned in True, False: 504 for isXReg in True, False: 505 buildFpCvtIntOp(isDouble, isSigned, isXReg) 506 507 fcvtFpSFpDCode = vfp64EnabledCheckCode + ''' 508 FPSCR fpscr = (FPSCR) FpscrExc; 509 uint64_t cDest = fplibConvert<uint32_t, uint64_t>(AA64FpOp1P0_uw, 510 FPCRRounding(fpscr), fpscr); 511 AA64FpDestP0_uw = cDest; 512 AA64FpDestP1_uw = cDest >> 32; 513 AA64FpDestP2_uw = 0; 514 AA64FpDestP3_uw = 0; 515 FpscrExc = fpscr; 516 ''' 517 fcvtFpSFpDIop = InstObjParams("fcvt", "FCvtFpSFpD", "FpRegRegOp", 518 { "code": fcvtFpSFpDCode, 519 "op_class": "FloatCvtOp" }, []) 520 header_output += FpRegRegOpDeclare.subst(fcvtFpSFpDIop); 521 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpSFpDIop); 522 exec_output += BasicExecute.subst(fcvtFpSFpDIop); 523 524 fcvtFpDFpSCode = vfp64EnabledCheckCode + ''' 525 FPSCR fpscr = (FPSCR) FpscrExc; 526 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 527 AA64FpDestP0_uw = fplibConvert<uint64_t, uint32_t>(cOp1, 528 FPCRRounding(fpscr), fpscr); 529 AA64FpDestP1_uw = 0; 530 AA64FpDestP2_uw = 0; 531 AA64FpDestP3_uw = 0; 532 FpscrExc = fpscr; 533 ''' 534 fcvtFpDFpSIop = InstObjParams("fcvt", "FcvtFpDFpS", "FpRegRegOp", 535 {"code": fcvtFpDFpSCode, 536 "op_class": "FloatCvtOp" }, []) 537 header_output += FpRegRegOpDeclare.subst(fcvtFpDFpSIop); 538 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpDFpSIop); 539 exec_output += BasicExecute.subst(fcvtFpDFpSIop); 540 541 # Half precision to single or double precision conversion 542 for isDouble in True, False: 543 code = vfp64EnabledCheckCode + ''' 544 FPSCR fpscr = (FPSCR) FpscrExc; 545 %s cDest = fplibConvert<uint16_t, uint%s_t>(AA64FpOp1P0_uw, 546 FPCRRounding(fpscr), fpscr); 547 ''' % ("uint64_t" if isDouble else "uint32_t", 548 "64" if isDouble else "32") 549 if isDouble: 550 code += ''' 551 AA64FpDestP0_uw = cDest; 552 AA64FpDestP1_uw = cDest >> 32; 553 ''' 554 else: 555 code += ''' 556 AA64FpDestP0_uw = cDest; 557 AA64FpDestP1_uw = 0; 558 ''' 559 code += ''' 560 AA64FpDestP2_uw = 0; 561 AA64FpDestP3_uw = 0; 562 FpscrExc = fpscr; 563 ''' 564 565 instName = "FcvtFpHFp%s" %("D" if isDouble else "S") 566 fcvtFpHFpIop = InstObjParams("fcvt", instName, "FpRegRegOp", 567 { "code": code, 568 "op_class": "FloatCvtOp" }, []) 569 header_output += FpRegRegOpDeclare.subst(fcvtFpHFpIop); 570 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpHFpIop); 571 exec_output += BasicExecute.subst(fcvtFpHFpIop); 572 573 # single or double precision to Half precision conversion 574 for isDouble in True, False: 575 code = vfp64EnabledCheckCode + ''' 576 FPSCR fpscr = (FPSCR) FpscrExc; 577 %s; 578 AA64FpDestP0_uw = fplibConvert<uint%s_t, uint16_t>(cOp1, 579 FPCRRounding(fpscr), fpscr); 580 AA64FpDestP1_uw = 0; 581 AA64FpDestP2_uw = 0; 582 AA64FpDestP3_uw = 0; 583 FpscrExc = fpscr; 584 ''' % ("uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32" 585 if isDouble else "uint32_t cOp1 = AA64FpOp1P0_uw", 586 "64" if isDouble else "32") 587 588 instName = "FcvtFp%sFpH" %("D" if isDouble else "S") 589 fcvtFpFpHIop = InstObjParams("fcvt", instName, "FpRegRegOp", 590 { "code": code, 591 "op_class": "FloatCvtOp" }, []) 592 header_output += FpRegRegOpDeclare.subst(fcvtFpFpHIop); 593 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpFpHIop); 594 exec_output += BasicExecute.subst(fcvtFpFpHIop); 595 596 # Build the various versions of the floating point compare instructions 597 def buildFCmpOp(isQuiet, isDouble, isImm): 598 global header_output, decoder_output, exec_output 599 600 fcmpCode = vfp64EnabledCheckCode + ''' 601 FPSCR fpscr = (FPSCR) FpscrExc; 602 %s cOp1 = %s; 603 ''' % ("uint64_t" if isDouble else "uint32_t", 604 "AA64FpDestP0_uw | (uint64_t)AA64FpDestP1_uw << 32" 605 if isDouble else "AA64FpDestP0_uw") 606 if isImm: 607 fcmpCode += ''' 608 %s cOp2 = imm; 609 ''' % ("uint64_t" if isDouble else "uint32_t") 610 else: 611 fcmpCode += ''' 612 %s cOp2 = %s; 613 ''' % ("uint64_t" if isDouble else "uint32_t", 614 "AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32" 615 if isDouble else "AA64FpOp1P0_uw") 616 fcmpCode += ''' 617 int cc = fplibCompare<uint%s_t>(cOp1, cOp2, %s, fpscr); 618 CondCodesNZ = cc >> 2 & 3; 619 CondCodesC = cc >> 1 & 1; 620 CondCodesV = cc & 1; 621 FpCondCodes = fpscr & FpCondCodesMask; 622 FpscrExc = fpscr; 623 ''' % ("64" if isDouble else "32", "false" if isQuiet else "true") 624 625 typeName = "Imm" if isImm else "Reg" 626 instName = "FCmp%s%s%s" %("" if isQuiet else "E", typeName, 627 "D" if isDouble else "S") 628 fcmpIop = InstObjParams("fcmp%s" %("" if isQuiet else "e"), instName, 629 "FpReg%sOp" %(typeName), 630 {"code": fcmpCode, 631 "op_class": "FloatCmpOp"}, []) 632 633 declareTemp = eval("FpReg%sOpDeclare" %(typeName)); 634 constructorTemp = eval("AA64FpReg%sOpConstructor" %(typeName)); 635 header_output += declareTemp.subst(fcmpIop); 636 decoder_output += constructorTemp.subst(fcmpIop); 637 exec_output += BasicExecute.subst(fcmpIop); 638 639 for isQuiet in True, False: 640 for isDouble in True, False: 641 for isImm in True, False: 642 buildFCmpOp(isQuiet, isDouble, isImm) 643 644 # Build the various versions of the conditional floating point compare 645 # instructions 646 def buildFCCmpOp(isQuiet, isDouble): 647 global header_output, decoder_output, exec_output 648 649 fccmpCode = vfp64EnabledCheckCode + ''' 650 FPSCR fpscr = (FPSCR) FpscrExc; 651 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) { 652 %s cOp1 = %s; 653 %s cOp2 = %s; 654 int cc = fplibCompare<uint%s_t>(cOp1, cOp2, %s, fpscr); 655 CondCodesNZ = cc >> 2 & 3; 656 CondCodesC = cc >> 1 & 1; 657 CondCodesV = cc & 1; 658 } else { 659 CondCodesNZ = (defCc >> 2) & 0x3; 660 CondCodesC = (defCc >> 1) & 0x1; 661 CondCodesV = defCc & 0x1; 662 } 663 FpCondCodes = fpscr & FpCondCodesMask; 664 FpscrExc = fpscr; 665 ''' % ("uint64_t" if isDouble else "uint32_t", 666 "AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32" 667 if isDouble else "AA64FpOp1P0_uw", 668 "uint64_t" if isDouble else "uint32_t", 669 "AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32" 670 if isDouble else "AA64FpOp2P0_uw", 671 "64" if isDouble else "32", "false" if isQuiet else "true") 672 673 instName = "FCCmp%sReg%s" %("" if isQuiet else "E", 674 "D" if isDouble else "S") 675 fccmpIop = InstObjParams("fccmp%s" %("" if isQuiet else "e"), 676 instName, "FpCondCompRegOp", 677 {"code": fccmpCode, 678 "op_class": "FloatCmpOp"}, []) 679 header_output += DataXCondCompRegDeclare.subst(fccmpIop); 680 decoder_output += DataXCondCompRegConstructor.subst(fccmpIop); 681 exec_output += BasicExecute.subst(fccmpIop); 682 683 for isQuiet in True, False: 684 for isDouble in True, False: 685 buildFCCmpOp(isQuiet, isDouble) 686 687}}; 688 689let {{ 690 691 header_output = "" 692 decoder_output = "" 693 exec_output = "" 694 695 # Generates the variants of the floating to fixed point instructions 696 def buildFpCvtFixedOp(isSigned, isDouble, isXReg): 697 global header_output, decoder_output, exec_output 698 699 fcvtFpFixedCode = vfp64EnabledCheckCode + ''' 700 FPSCR fpscr = (FPSCR) FpscrExc; 701 ''' 702 if isDouble: 703 fcvtFpFixedCode += ''' 704 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 705 ''' 706 else: 707 fcvtFpFixedCode += "uint32_t cOp1 = AA64FpOp1P0_uw;" 708 fcvtFpFixedCode += ''' 709 %sDest = fplibFPToFixed<uint%s_t, uint%s_t>(cOp1, 64 - imm, %s, 710 FPRounding_ZERO, fpscr); 711 FpscrExc = fpscr; 712 ''' %("X" if isXReg else "W", 713 "64" if isDouble else "32", 714 "64" if isXReg else "32", 715 "false" if isSigned else "true") 716 717 instName = "FcvtFp%sFixed%s%s" %("S" if isSigned else "U", 718 "D" if isDouble else "S", 719 "X" if isXReg else "W") 720 mnem = "fcvtz%s" %("s" if isSigned else "u") 721 fcvtFpFixedIop = InstObjParams(mnem, instName, "FpRegRegImmOp", 722 { "code": fcvtFpFixedCode, 723 "op_class": "FloatCvtOp" }, []) 724 header_output += FpRegRegImmOpDeclare.subst(fcvtFpFixedIop); 725 decoder_output += AA64FpRegRegImmOpConstructor.subst(fcvtFpFixedIop); 726 exec_output += BasicExecute.subst(fcvtFpFixedIop); 727 728 # Generates the variants of the fixed to floating point instructions 729 def buildFixedCvtFpOp(isSigned, isDouble, isXReg): 730 global header_output, decoder_output, exec_output 731 732 srcRegType = "X" if isXReg else "W" 733 fcvtFixedFpCode = vfp64EnabledCheckCode + ''' 734 FPSCR fpscr = (FPSCR) FpscrExc; 735 %s result = fplibFixedToFP<uint%s_t>((%s%s_t)%sOp1, 64 - imm, 736 %s, FPCRRounding(fpscr), fpscr); 737 ''' %("uint64_t" if isDouble else "uint32_t", 738 "64" if isDouble else "32", 739 "int" if isSigned else "uint", "64" if isXReg else "32", 740 srcRegType, 741 "false" if isSigned else "true") 742 if isDouble: 743 fcvtFixedFpCode += ''' 744 AA64FpDestP0_uw = result; 745 AA64FpDestP1_uw = result >> 32; 746 ''' 747 else: 748 fcvtFixedFpCode += ''' 749 AA64FpDestP0_uw = result; 750 AA64FpDestP1_uw = 0; 751 ''' 752 fcvtFixedFpCode += ''' 753 AA64FpDestP2_uw = 0; 754 AA64FpDestP3_uw = 0; 755 FpscrExc = fpscr; 756 ''' 757 758 instName = "Fcvt%sFixedFp%s%s" %("S" if isSigned else "U", 759 "D" if isDouble else "S", 760 srcRegType) 761 mnem = "%scvtf" %("s" if isSigned else "u") 762 fcvtFixedFpIop = InstObjParams(mnem, instName, "FpRegRegImmOp", 763 { "code": fcvtFixedFpCode, 764 "op_class": "FloatCvtOp" }, []) 765 header_output += FpRegRegImmOpDeclare.subst(fcvtFixedFpIop); 766 decoder_output += FpRegRegImmOpConstructor.subst(fcvtFixedFpIop); 767 exec_output += BasicExecute.subst(fcvtFixedFpIop); 768 769 # loop over the variants building the instructions for each 770 for isXReg in True, False: 771 for isDouble in True, False: 772 for isSigned in True, False: 773 buildFpCvtFixedOp(isSigned, isDouble, isXReg) 774 buildFixedCvtFpOp(isSigned, isDouble, isXReg) 775}}; 776 777let {{ 778 779 header_output = "" 780 decoder_output = "" 781 exec_output = "" 782 783 for isDouble in True, False: 784 code = ''' 785 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) { 786 AA64FpDestP0_uw = AA64FpOp1P0_uw; 787 ''' 788 if isDouble: 789 code += ''' 790 AA64FpDestP1_uw = AA64FpOp1P1_uw; 791 } else { 792 AA64FpDestP0_uw = AA64FpOp2P0_uw; 793 AA64FpDestP1_uw = AA64FpOp2P1_uw; 794 } 795 ''' 796 else: 797 code += ''' 798 } else { 799 AA64FpDestP0_uw = AA64FpOp2P0_uw; 800 } 801 AA64FpDestP1_uw = 0; 802 ''' 803 code += ''' 804 AA64FpDestP2_uw = 0; 805 AA64FpDestP3_uw = 0; 806 ''' 807 808 iop = InstObjParams("fcsel", "FCSel%s" %("D" if isDouble else "S"), 809 "FpCondSelOp", { "code": code, 810 "op_class": "FloatCvtOp" }) 811 header_output += DataXCondSelDeclare.subst(iop) 812 decoder_output += DataXCondSelConstructor.subst(iop) 813 exec_output += BasicExecute.subst(iop) 814}};
| 493}}; 494 495let {{ 496 497 header_output = "" 498 decoder_output = "" 499 exec_output = "" 500 501 # Creates the integer to floating point instructions, including variants for 502 # signed/unsigned, float/double, etc 503 for regL, regOpL, width in [["W", "w", 32], 504 ["X", "d", 64]]: 505 for isDouble in True, False: 506 for us, usCode in [["U", "uint%d_t cSrc = %sOp1_u%s;" %(width, regL, regOpL)], 507 ["S", "int%d_t cSrc = %sOp1_u%s;" %(width, regL, regOpL)]]: 508 fcvtIntFpDCode = vfp64EnabledCheckCode + ''' 509 FPSCR fpscr = (FPSCR) FpscrExc; 510 %s 511 ''' %(usCode) 512 513 if isDouble: 514 fcvtIntFpDCode += ''' 515 uint64_t cDest = fplibFixedToFP<uint64_t>(cSrc, 0, 516 %s, FPCRRounding(fpscr), fpscr); 517 AA64FpDestP0_uw = cDest; 518 AA64FpDestP1_uw = cDest >> 32; 519 ''' % ("true" if us == "U" else "false") 520 else: 521 fcvtIntFpDCode += ''' 522 uint32_t cDest = fplibFixedToFP<uint32_t>(cSrc, 0, 523 %s, FPCRRounding(fpscr), fpscr); 524 AA64FpDestP0_uw = cDest; 525 AA64FpDestP1_uw = 0; 526 ''' % ("true" if us == "U" else "false") 527 fcvtIntFpDCode += ''' 528 AA64FpDestP2_uw = 0; 529 AA64FpDestP3_uw = 0; 530 FpscrExc = fpscr; 531 ''' 532 533 instName = "Fcvt%s%sIntFp%s" %(regL, us, "D" if isDouble else "S") 534 mnem = "%scvtf" %(us.lower()) 535 fcvtIntFpDIop = InstObjParams(mnem, instName, "FpRegRegOp", 536 { "code": fcvtIntFpDCode, 537 "op_class": "FloatCvtOp" }, []) 538 header_output += FpRegRegOpDeclare.subst(fcvtIntFpDIop); 539 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtIntFpDIop); 540 exec_output += BasicExecute.subst(fcvtIntFpDIop); 541 542 # Generates the floating point to integer conversion instructions in various 543 # variants, eg signed/unsigned 544 def buildFpCvtIntOp(isDouble, isSigned, isXReg): 545 global header_output, decoder_output, exec_output 546 547 for rmode, roundingMode in [["N", "FPRounding_TIEEVEN"], 548 ["P", "FPRounding_POSINF"], 549 ["M", "FPRounding_NEGINF"], 550 ["Z", "FPRounding_ZERO"], 551 ["A", "FPRounding_TIEAWAY"]]: 552 fcvtFpIntCode = vfp64EnabledCheckCode + ''' 553 FPSCR fpscr = (FPSCR) FpscrExc;''' 554 if isDouble: 555 fcvtFpIntCode += ''' 556 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 557 ''' 558 else: 559 fcvtFpIntCode += "uint32_t cOp1 = AA64FpOp1P0_uw;" 560 561 fcvtFpIntCode += ''' 562 %sDest = fplibFPToFixed<uint%s_t, uint%s_t>(cOp1, 0, %s, %s, fpscr); 563 FpscrExc = fpscr; 564 ''' %("X" if isXReg else "W", 565 "64" if isDouble else "32", 566 "64" if isXReg else "32", 567 "false" if isSigned else "true", 568 roundingMode) 569 570 instName = "FcvtFp%sInt%s%s%s" %("S" if isSigned else "U", 571 "X" if isXReg else "W", 572 "D" if isDouble else "S", rmode) 573 mnem = "fcvt%s%s" %(rmode, "s" if isSigned else "u") 574 fcvtFpIntIop = InstObjParams(mnem, instName, "FpRegRegOp", 575 { "code": fcvtFpIntCode, 576 "op_class": "FloatCvtOp" }, []) 577 header_output += FpRegRegOpDeclare.subst(fcvtFpIntIop); 578 decoder_output += FpRegRegOpConstructor.subst(fcvtFpIntIop); 579 exec_output += BasicExecute.subst(fcvtFpIntIop); 580 581 # Now actually do the building with the different variants 582 for isDouble in True, False: 583 for isSigned in True, False: 584 for isXReg in True, False: 585 buildFpCvtIntOp(isDouble, isSigned, isXReg) 586 587 fcvtFpSFpDCode = vfp64EnabledCheckCode + ''' 588 FPSCR fpscr = (FPSCR) FpscrExc; 589 uint64_t cDest = fplibConvert<uint32_t, uint64_t>(AA64FpOp1P0_uw, 590 FPCRRounding(fpscr), fpscr); 591 AA64FpDestP0_uw = cDest; 592 AA64FpDestP1_uw = cDest >> 32; 593 AA64FpDestP2_uw = 0; 594 AA64FpDestP3_uw = 0; 595 FpscrExc = fpscr; 596 ''' 597 fcvtFpSFpDIop = InstObjParams("fcvt", "FCvtFpSFpD", "FpRegRegOp", 598 { "code": fcvtFpSFpDCode, 599 "op_class": "FloatCvtOp" }, []) 600 header_output += FpRegRegOpDeclare.subst(fcvtFpSFpDIop); 601 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpSFpDIop); 602 exec_output += BasicExecute.subst(fcvtFpSFpDIop); 603 604 fcvtFpDFpSCode = vfp64EnabledCheckCode + ''' 605 FPSCR fpscr = (FPSCR) FpscrExc; 606 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 607 AA64FpDestP0_uw = fplibConvert<uint64_t, uint32_t>(cOp1, 608 FPCRRounding(fpscr), fpscr); 609 AA64FpDestP1_uw = 0; 610 AA64FpDestP2_uw = 0; 611 AA64FpDestP3_uw = 0; 612 FpscrExc = fpscr; 613 ''' 614 fcvtFpDFpSIop = InstObjParams("fcvt", "FcvtFpDFpS", "FpRegRegOp", 615 {"code": fcvtFpDFpSCode, 616 "op_class": "FloatCvtOp" }, []) 617 header_output += FpRegRegOpDeclare.subst(fcvtFpDFpSIop); 618 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpDFpSIop); 619 exec_output += BasicExecute.subst(fcvtFpDFpSIop); 620 621 # Half precision to single or double precision conversion 622 for isDouble in True, False: 623 code = vfp64EnabledCheckCode + ''' 624 FPSCR fpscr = (FPSCR) FpscrExc; 625 %s cDest = fplibConvert<uint16_t, uint%s_t>(AA64FpOp1P0_uw, 626 FPCRRounding(fpscr), fpscr); 627 ''' % ("uint64_t" if isDouble else "uint32_t", 628 "64" if isDouble else "32") 629 if isDouble: 630 code += ''' 631 AA64FpDestP0_uw = cDest; 632 AA64FpDestP1_uw = cDest >> 32; 633 ''' 634 else: 635 code += ''' 636 AA64FpDestP0_uw = cDest; 637 AA64FpDestP1_uw = 0; 638 ''' 639 code += ''' 640 AA64FpDestP2_uw = 0; 641 AA64FpDestP3_uw = 0; 642 FpscrExc = fpscr; 643 ''' 644 645 instName = "FcvtFpHFp%s" %("D" if isDouble else "S") 646 fcvtFpHFpIop = InstObjParams("fcvt", instName, "FpRegRegOp", 647 { "code": code, 648 "op_class": "FloatCvtOp" }, []) 649 header_output += FpRegRegOpDeclare.subst(fcvtFpHFpIop); 650 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpHFpIop); 651 exec_output += BasicExecute.subst(fcvtFpHFpIop); 652 653 # single or double precision to Half precision conversion 654 for isDouble in True, False: 655 code = vfp64EnabledCheckCode + ''' 656 FPSCR fpscr = (FPSCR) FpscrExc; 657 %s; 658 AA64FpDestP0_uw = fplibConvert<uint%s_t, uint16_t>(cOp1, 659 FPCRRounding(fpscr), fpscr); 660 AA64FpDestP1_uw = 0; 661 AA64FpDestP2_uw = 0; 662 AA64FpDestP3_uw = 0; 663 FpscrExc = fpscr; 664 ''' % ("uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32" 665 if isDouble else "uint32_t cOp1 = AA64FpOp1P0_uw", 666 "64" if isDouble else "32") 667 668 instName = "FcvtFp%sFpH" %("D" if isDouble else "S") 669 fcvtFpFpHIop = InstObjParams("fcvt", instName, "FpRegRegOp", 670 { "code": code, 671 "op_class": "FloatCvtOp" }, []) 672 header_output += FpRegRegOpDeclare.subst(fcvtFpFpHIop); 673 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpFpHIop); 674 exec_output += BasicExecute.subst(fcvtFpFpHIop); 675 676 # Build the various versions of the floating point compare instructions 677 def buildFCmpOp(isQuiet, isDouble, isImm): 678 global header_output, decoder_output, exec_output 679 680 fcmpCode = vfp64EnabledCheckCode + ''' 681 FPSCR fpscr = (FPSCR) FpscrExc; 682 %s cOp1 = %s; 683 ''' % ("uint64_t" if isDouble else "uint32_t", 684 "AA64FpDestP0_uw | (uint64_t)AA64FpDestP1_uw << 32" 685 if isDouble else "AA64FpDestP0_uw") 686 if isImm: 687 fcmpCode += ''' 688 %s cOp2 = imm; 689 ''' % ("uint64_t" if isDouble else "uint32_t") 690 else: 691 fcmpCode += ''' 692 %s cOp2 = %s; 693 ''' % ("uint64_t" if isDouble else "uint32_t", 694 "AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32" 695 if isDouble else "AA64FpOp1P0_uw") 696 fcmpCode += ''' 697 int cc = fplibCompare<uint%s_t>(cOp1, cOp2, %s, fpscr); 698 CondCodesNZ = cc >> 2 & 3; 699 CondCodesC = cc >> 1 & 1; 700 CondCodesV = cc & 1; 701 FpCondCodes = fpscr & FpCondCodesMask; 702 FpscrExc = fpscr; 703 ''' % ("64" if isDouble else "32", "false" if isQuiet else "true") 704 705 typeName = "Imm" if isImm else "Reg" 706 instName = "FCmp%s%s%s" %("" if isQuiet else "E", typeName, 707 "D" if isDouble else "S") 708 fcmpIop = InstObjParams("fcmp%s" %("" if isQuiet else "e"), instName, 709 "FpReg%sOp" %(typeName), 710 {"code": fcmpCode, 711 "op_class": "FloatCmpOp"}, []) 712 713 declareTemp = eval("FpReg%sOpDeclare" %(typeName)); 714 constructorTemp = eval("AA64FpReg%sOpConstructor" %(typeName)); 715 header_output += declareTemp.subst(fcmpIop); 716 decoder_output += constructorTemp.subst(fcmpIop); 717 exec_output += BasicExecute.subst(fcmpIop); 718 719 for isQuiet in True, False: 720 for isDouble in True, False: 721 for isImm in True, False: 722 buildFCmpOp(isQuiet, isDouble, isImm) 723 724 # Build the various versions of the conditional floating point compare 725 # instructions 726 def buildFCCmpOp(isQuiet, isDouble): 727 global header_output, decoder_output, exec_output 728 729 fccmpCode = vfp64EnabledCheckCode + ''' 730 FPSCR fpscr = (FPSCR) FpscrExc; 731 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) { 732 %s cOp1 = %s; 733 %s cOp2 = %s; 734 int cc = fplibCompare<uint%s_t>(cOp1, cOp2, %s, fpscr); 735 CondCodesNZ = cc >> 2 & 3; 736 CondCodesC = cc >> 1 & 1; 737 CondCodesV = cc & 1; 738 } else { 739 CondCodesNZ = (defCc >> 2) & 0x3; 740 CondCodesC = (defCc >> 1) & 0x1; 741 CondCodesV = defCc & 0x1; 742 } 743 FpCondCodes = fpscr & FpCondCodesMask; 744 FpscrExc = fpscr; 745 ''' % ("uint64_t" if isDouble else "uint32_t", 746 "AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32" 747 if isDouble else "AA64FpOp1P0_uw", 748 "uint64_t" if isDouble else "uint32_t", 749 "AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32" 750 if isDouble else "AA64FpOp2P0_uw", 751 "64" if isDouble else "32", "false" if isQuiet else "true") 752 753 instName = "FCCmp%sReg%s" %("" if isQuiet else "E", 754 "D" if isDouble else "S") 755 fccmpIop = InstObjParams("fccmp%s" %("" if isQuiet else "e"), 756 instName, "FpCondCompRegOp", 757 {"code": fccmpCode, 758 "op_class": "FloatCmpOp"}, []) 759 header_output += DataXCondCompRegDeclare.subst(fccmpIop); 760 decoder_output += DataXCondCompRegConstructor.subst(fccmpIop); 761 exec_output += BasicExecute.subst(fccmpIop); 762 763 for isQuiet in True, False: 764 for isDouble in True, False: 765 buildFCCmpOp(isQuiet, isDouble) 766 767}}; 768 769let {{ 770 771 header_output = "" 772 decoder_output = "" 773 exec_output = "" 774 775 # Generates the variants of the floating to fixed point instructions 776 def buildFpCvtFixedOp(isSigned, isDouble, isXReg): 777 global header_output, decoder_output, exec_output 778 779 fcvtFpFixedCode = vfp64EnabledCheckCode + ''' 780 FPSCR fpscr = (FPSCR) FpscrExc; 781 ''' 782 if isDouble: 783 fcvtFpFixedCode += ''' 784 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 785 ''' 786 else: 787 fcvtFpFixedCode += "uint32_t cOp1 = AA64FpOp1P0_uw;" 788 fcvtFpFixedCode += ''' 789 %sDest = fplibFPToFixed<uint%s_t, uint%s_t>(cOp1, 64 - imm, %s, 790 FPRounding_ZERO, fpscr); 791 FpscrExc = fpscr; 792 ''' %("X" if isXReg else "W", 793 "64" if isDouble else "32", 794 "64" if isXReg else "32", 795 "false" if isSigned else "true") 796 797 instName = "FcvtFp%sFixed%s%s" %("S" if isSigned else "U", 798 "D" if isDouble else "S", 799 "X" if isXReg else "W") 800 mnem = "fcvtz%s" %("s" if isSigned else "u") 801 fcvtFpFixedIop = InstObjParams(mnem, instName, "FpRegRegImmOp", 802 { "code": fcvtFpFixedCode, 803 "op_class": "FloatCvtOp" }, []) 804 header_output += FpRegRegImmOpDeclare.subst(fcvtFpFixedIop); 805 decoder_output += AA64FpRegRegImmOpConstructor.subst(fcvtFpFixedIop); 806 exec_output += BasicExecute.subst(fcvtFpFixedIop); 807 808 # Generates the variants of the fixed to floating point instructions 809 def buildFixedCvtFpOp(isSigned, isDouble, isXReg): 810 global header_output, decoder_output, exec_output 811 812 srcRegType = "X" if isXReg else "W" 813 fcvtFixedFpCode = vfp64EnabledCheckCode + ''' 814 FPSCR fpscr = (FPSCR) FpscrExc; 815 %s result = fplibFixedToFP<uint%s_t>((%s%s_t)%sOp1, 64 - imm, 816 %s, FPCRRounding(fpscr), fpscr); 817 ''' %("uint64_t" if isDouble else "uint32_t", 818 "64" if isDouble else "32", 819 "int" if isSigned else "uint", "64" if isXReg else "32", 820 srcRegType, 821 "false" if isSigned else "true") 822 if isDouble: 823 fcvtFixedFpCode += ''' 824 AA64FpDestP0_uw = result; 825 AA64FpDestP1_uw = result >> 32; 826 ''' 827 else: 828 fcvtFixedFpCode += ''' 829 AA64FpDestP0_uw = result; 830 AA64FpDestP1_uw = 0; 831 ''' 832 fcvtFixedFpCode += ''' 833 AA64FpDestP2_uw = 0; 834 AA64FpDestP3_uw = 0; 835 FpscrExc = fpscr; 836 ''' 837 838 instName = "Fcvt%sFixedFp%s%s" %("S" if isSigned else "U", 839 "D" if isDouble else "S", 840 srcRegType) 841 mnem = "%scvtf" %("s" if isSigned else "u") 842 fcvtFixedFpIop = InstObjParams(mnem, instName, "FpRegRegImmOp", 843 { "code": fcvtFixedFpCode, 844 "op_class": "FloatCvtOp" }, []) 845 header_output += FpRegRegImmOpDeclare.subst(fcvtFixedFpIop); 846 decoder_output += FpRegRegImmOpConstructor.subst(fcvtFixedFpIop); 847 exec_output += BasicExecute.subst(fcvtFixedFpIop); 848 849 # loop over the variants building the instructions for each 850 for isXReg in True, False: 851 for isDouble in True, False: 852 for isSigned in True, False: 853 buildFpCvtFixedOp(isSigned, isDouble, isXReg) 854 buildFixedCvtFpOp(isSigned, isDouble, isXReg) 855}}; 856 857let {{ 858 859 header_output = "" 860 decoder_output = "" 861 exec_output = "" 862 863 for isDouble in True, False: 864 code = ''' 865 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) { 866 AA64FpDestP0_uw = AA64FpOp1P0_uw; 867 ''' 868 if isDouble: 869 code += ''' 870 AA64FpDestP1_uw = AA64FpOp1P1_uw; 871 } else { 872 AA64FpDestP0_uw = AA64FpOp2P0_uw; 873 AA64FpDestP1_uw = AA64FpOp2P1_uw; 874 } 875 ''' 876 else: 877 code += ''' 878 } else { 879 AA64FpDestP0_uw = AA64FpOp2P0_uw; 880 } 881 AA64FpDestP1_uw = 0; 882 ''' 883 code += ''' 884 AA64FpDestP2_uw = 0; 885 AA64FpDestP3_uw = 0; 886 ''' 887 888 iop = InstObjParams("fcsel", "FCSel%s" %("D" if isDouble else "S"), 889 "FpCondSelOp", { "code": code, 890 "op_class": "FloatCvtOp" }) 891 header_output += DataXCondSelDeclare.subst(iop) 892 decoder_output += DataXCondSelConstructor.subst(iop) 893 exec_output += BasicExecute.subst(iop) 894}};
|