fp.isa (13978:896f9f7a1d16) fp.isa (13979:1e0c4607ac12)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2011, 2016-2019 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

--- 2020 unchanged lines hidden (view full) ---

2029 if (!isInt and size == 3) {
2030 return (IntRegIndex)((bits(machInst, 22) << 5) |
2031 (bits(machInst, 15, 12) << 1));
2032 } else {
2033 return (IntRegIndex)(bits(machInst, 22) |
2034 (bits(machInst, 15, 12) << 1));
2035 }
2036 }
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2011, 2016-2019 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

--- 2020 unchanged lines hidden (view full) ---

2029 if (!isInt and size == 3) {
2030 return (IntRegIndex)((bits(machInst, 22) << 5) |
2031 (bits(machInst, 15, 12) << 1));
2032 } else {
2033 return (IntRegIndex)(bits(machInst, 22) |
2034 (bits(machInst, 15, 12) << 1));
2035 }
2036 }
2037
2037 IntRegIndex decodeFpVm(ExtMachInst machInst, uint32_t size, bool isInt)
2038 {
2039 if (!isInt and size == 3) {
2040 return (IntRegIndex)((bits(machInst, 5) << 5) |
2041 (bits(machInst, 3, 0) << 1));
2042 } else {
2043 return (IntRegIndex)(bits(machInst, 5) |
2044 (bits(machInst, 3, 0) << 1));
2045 }
2046 }
2038 IntRegIndex decodeFpVm(ExtMachInst machInst, uint32_t size, bool isInt)
2039 {
2040 if (!isInt and size == 3) {
2041 return (IntRegIndex)((bits(machInst, 5) << 5) |
2042 (bits(machInst, 3, 0) << 1));
2043 } else {
2044 return (IntRegIndex)(bits(machInst, 5) |
2045 (bits(machInst, 3, 0) << 1));
2046 }
2047 }
2047 StaticInstPtr
2048 decodeShortFpTransfer(ExtMachInst machInst)
2048
2049 IntRegIndex decodeFpVn(ExtMachInst machInst, uint32_t size)
2049 {
2050 {
2050 const uint32_t l = bits(machInst, 20);
2051 const uint32_t c = bits(machInst, 8);
2052 const uint32_t a = bits(machInst, 23, 21);
2053 const uint32_t q = bits(machInst, 6, 5);
2054 const uint32_t o1 = bits(machInst, 18);
2055 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
2056 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
2057 // Determine if this is backported aarch64 FP instruction
2058 const bool b31_b24 = bits(machInst, 31, 24) == 0xFE;
2059 const bool b23 = bits(machInst, 23);
2060 const bool b21_b19 = bits(machInst, 21, 19) == 0x7;
2061 const bool b11_b9 = bits(machInst, 11, 9) == 0x5;
2062 const uint32_t size = bits(machInst, 9, 8);
2063 const bool op3 = bits(machInst, 6);
2064 const bool b4 = bits(machInst, 4) == 0x0;
2065 const uint32_t rm = bits(machInst, 17, 16);
2066 IntRegIndex vd = decodeFpVd(machInst, size, false);
2067 IntRegIndex vm = decodeFpVm(machInst, size, false);
2068 IntRegIndex vdInt = decodeFpVd(machInst, size, true);
2069 if (b31_b24 && b23 && b21_b19 && b11_b9 && op3 && b4) {
2051 if (size == 3) {
2052 return (IntRegIndex)((bits(machInst, 7) << 5) |
2053 (bits(machInst, 19, 16) << 1));
2054 } else {
2055 return (IntRegIndex)(bits(machInst, 7) |
2056 (bits(machInst, 19, 16) << 1));
2057 }
2058 }
2059
2060 StaticInstPtr
2061 decodeFloatingPointDataProcessing(ExtMachInst machInst) {
2062 const uint32_t op0 = bits(machInst, 23, 20);
2063 const uint32_t op1 = bits(machInst, 19, 16);
2064 const uint32_t op2 = bits(machInst, 9, 8);
2065 const uint32_t op3 = bits(machInst, 6);
2066 const uint32_t rm = bits(machInst, 17, 16);
2067 const uint32_t size = bits(machInst, 9, 8);
2068 IntRegIndex vd = decodeFpVd(machInst, size, false);
2069 IntRegIndex vm = decodeFpVm(machInst, size, false);
2070 IntRegIndex vdInt = decodeFpVd(machInst, size, true);
2071 IntRegIndex vn = decodeFpVn(machInst, size);
2072 if (bits(machInst, 31, 24) == 0xFE && !bits(machInst, 4)) {
2073 if (bits(op0, 3) == 0 && op2 != 0 && !op3){
2074 ConditionCode cond;
2075 switch(bits(machInst, 21, 20)) {
2076 case 0x0: cond = COND_EQ; break;
2077 case 0x1: cond = COND_VS; break;
2078 case 0x2: cond = COND_GE; break;
2079 case 0x3: cond = COND_GT; break;
2080 }
2081 if (size == 3) {
2082 return new VselD(machInst, vd, vn, vm, cond);
2083 } else {
2084 return new VselS(machInst, vd, vn, vm, cond);
2085 }
2086 } else if (bits(op0, 3) == 1 && bits(op0, 1, 0) == 0 && op2 != 0) {
2087 const bool op = bits(machInst, 6);
2088 if (op) {
2089 if (size == 1) {
2090 return new FailUnimplemented("vminnm.f16", machInst);
2091 }
2092 return decodeNeonSizeSingleDouble<VminnmS, VminnmD>(
2093 size, machInst, vd, vn, vm);
2094 } else {
2095 if (size == 1) {
2096 return new FailUnimplemented("vmaxnm.f16", machInst);
2097 }
2098 return decodeNeonSizeSingleDouble<VmaxnmS, VmaxnmD>(
2099 size, machInst, vd, vn, vm);
2100 }
2101 } else if (bits(op0, 3) && bits(op0, 1, 0) == 3 &&
2102 bits(op1, 3) && op2 != 0 && op3)
2103 {
2104 const uint32_t o1 = bits(machInst, 18);
2070 if (o1 == 0) {
2105 if (o1 == 0) {
2071 // VINT* Integer Rounding Instruction
2072 if (size == 3) {
2073 switch(rm) {
2074 case 0x0:
2075 return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm,
2076 true);
2077 case 0x1:
2078 return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm,
2079 true);

--- 20 unchanged lines hidden (view full) ---

2100 return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm,
2101 false);
2102 default: return new Unknown(machInst);
2103 }
2104 }
2105 } else {
2106 const bool op = bits(machInst, 7);
2107 switch(rm) {
2106 if (size == 3) {
2107 switch(rm) {
2108 case 0x0:
2109 return decodeVfpRegRegOp<VRIntAD>(machInst, vd, vm,
2110 true);
2111 case 0x1:
2112 return decodeVfpRegRegOp<VRIntND>(machInst, vd, vm,
2113 true);

--- 20 unchanged lines hidden (view full) ---

2134 return decodeVfpRegRegOp<VRIntMS>(machInst, vd, vm,
2135 false);
2136 default: return new Unknown(machInst);
2137 }
2138 }
2139 } else {
2140 const bool op = bits(machInst, 7);
2141 switch(rm) {
2108 case 0x0:
2142 case 0x0:
2109 switch(size) {
2143 switch(size) {
2110 case 0x0:
2144 case 0x0:
2111 return new Unknown(machInst);
2145 return new Unknown(machInst);
2112 case 0x1:
2146 case 0x1:
2113 return new FailUnimplemented(
2114 "vcvta.u32.f16", machInst);
2147 return new FailUnimplemented(
2148 "vcvta.u32.f16", machInst);
2115 case 0x2:
2149 case 0x2:
2116 if (op) {
2117 return new VcvtaFpSIntS(machInst, vdInt, vm);
2118 } else {
2119 return new VcvtaFpUIntS(machInst, vdInt, vm);
2120 }
2150 if (op) {
2151 return new VcvtaFpSIntS(machInst, vdInt, vm);
2152 } else {
2153 return new VcvtaFpUIntS(machInst, vdInt, vm);
2154 }
2121 case 0x3:
2155 case 0x3:
2122 if (op) {
2123 return new VcvtaFpSIntD(machInst, vdInt, vm);
2124 } else {
2125 return new VcvtaFpUIntD(machInst, vdInt, vm);
2126 }
2156 if (op) {
2157 return new VcvtaFpSIntD(machInst, vdInt, vm);
2158 } else {
2159 return new VcvtaFpUIntD(machInst, vdInt, vm);
2160 }
2127 default: return new Unknown(machInst);
2161 default: return new Unknown(machInst);
2128 }
2162 }
2129 case 0x1:
2163 case 0x1:
2130 switch(size) {
2164 switch(size) {
2131 case 0x0:
2165 case 0x0:
2132 return new Unknown(machInst);
2166 return new Unknown(machInst);
2133 case 0x1:
2167 case 0x1:
2134 return new FailUnimplemented(
2135 "vcvtn.u32.f16", machInst);
2168 return new FailUnimplemented(
2169 "vcvtn.u32.f16", machInst);
2136 case 0x2:
2170 case 0x2:
2137 if (op) {
2138 return new VcvtnFpSIntS(machInst, vdInt, vm);
2139 } else {
2140 return new VcvtnFpUIntS(machInst, vdInt, vm);
2141 }
2171 if (op) {
2172 return new VcvtnFpSIntS(machInst, vdInt, vm);
2173 } else {
2174 return new VcvtnFpUIntS(machInst, vdInt, vm);
2175 }
2142 case 0x3:
2176 case 0x3:
2143 if (op) {
2144 return new VcvtnFpSIntD(machInst, vdInt, vm);
2145 } else {
2146 return new VcvtnFpUIntD(machInst, vdInt, vm);
2147 }
2177 if (op) {
2178 return new VcvtnFpSIntD(machInst, vdInt, vm);
2179 } else {
2180 return new VcvtnFpUIntD(machInst, vdInt, vm);
2181 }
2148 default: return new Unknown(machInst);
2182 default: return new Unknown(machInst);
2149 }
2183 }
2150 case 0x2:
2184 case 0x2:
2151 switch(size) {
2185 switch(size) {
2152 case 0x0:
2186 case 0x0:
2153 return new Unknown(machInst);
2187 return new Unknown(machInst);
2154 case 0x1:
2188 case 0x1:
2155 return new FailUnimplemented(
2156 "vcvtp.u32.f16", machInst);
2189 return new FailUnimplemented(
2190 "vcvtp.u32.f16", machInst);
2157 case 0x2:
2191 case 0x2:
2158 if (op) {
2159 return new VcvtpFpSIntS(machInst, vdInt, vm);
2160 } else {
2161 return new VcvtpFpUIntS(machInst, vdInt, vm);
2162 }
2192 if (op) {
2193 return new VcvtpFpSIntS(machInst, vdInt, vm);
2194 } else {
2195 return new VcvtpFpUIntS(machInst, vdInt, vm);
2196 }
2163 case 0x3:
2197 case 0x3:
2164 if (op) {
2165 return new VcvtpFpSIntD(machInst, vdInt, vm);
2166 } else {
2167 return new VcvtpFpUIntD(machInst, vdInt, vm);
2168 }
2198 if (op) {
2199 return new VcvtpFpSIntD(machInst, vdInt, vm);
2200 } else {
2201 return new VcvtpFpUIntD(machInst, vdInt, vm);
2202 }
2169 default: return new Unknown(machInst);
2203 default: return new Unknown(machInst);
2170 }
2204 }
2171 case 0x3:
2205 case 0x3:
2172 switch(size) {
2206 switch(size) {
2173 case 0x0:
2207 case 0x0:
2174 return new Unknown(machInst);
2208 return new Unknown(machInst);
2175 case 0x1:
2209 case 0x1:
2176 return new FailUnimplemented(
2177 "vcvtm.u32.f16", machInst);
2210 return new FailUnimplemented(
2211 "vcvtm.u32.f16", machInst);
2178 case 0x2:
2212 case 0x2:
2179 if (op) {
2180 return new VcvtmFpSIntS(machInst, vdInt, vm);
2181 } else {
2182 return new VcvtmFpUIntS(machInst, vdInt, vm);
2183 }
2213 if (op) {
2214 return new VcvtmFpSIntS(machInst, vdInt, vm);
2215 } else {
2216 return new VcvtmFpUIntS(machInst, vdInt, vm);
2217 }
2184 case 0x3:
2218 case 0x3:
2185 if (op) {
2186 return new VcvtmFpSIntD(machInst, vdInt, vm);
2187 } else {
2188 return new VcvtmFpUIntD(machInst, vdInt, vm);
2189 }
2219 if (op) {
2220 return new VcvtmFpSIntD(machInst, vdInt, vm);
2221 } else {
2222 return new VcvtmFpUIntD(machInst, vdInt, vm);
2223 }
2190 default: return new Unknown(machInst);
2224 default: return new Unknown(machInst);
2191 }
2225 }
2192 default: return new Unknown(machInst);
2226 default: return new Unknown(machInst);
2193 }
2194 }
2227 }
2228 }
2195 } else if (b31_b24 && !b23 && b11_b9 && !op3 && b4){
2196 // VSEL* floating point conditional select
2197
2198 ConditionCode cond;
2199 switch(bits(machInst, 21, 20)) {
2200 case 0x0: cond = COND_EQ; break;
2201 case 0x1: cond = COND_VS; break;
2202 case 0x2: cond = COND_GE; break;
2203 case 0x3: cond = COND_GT; break;
2204 }
2205
2206 if (size == 3) {
2207 const IntRegIndex vn =
2208 (IntRegIndex)((bits(machInst, 7) << 5) |
2209 (bits(machInst, 19, 16) << 1));
2210 return new VselD(machInst, vd, vn, vm, cond);
2211 } else {
2212 const IntRegIndex vn =
2213 (IntRegIndex)((bits(machInst, 19, 16) << 1) |
2214 bits(machInst, 7));
2215 return new VselS(machInst, vd, vn, vm, cond);
2216 }
2217 } else {
2218 return new Unknown(machInst);
2219 }
2229 } else {
2230 return new Unknown(machInst);
2231 }
2232 } else {
2233 return new Unknown(machInst);
2220 }
2234 }
2235 }
2236
2237 StaticInstPtr
2238 decodeShortFpTransfer(ExtMachInst machInst)
2239 {
2240 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
2241 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
2242 return decodeFloatingPointDataProcessing(machInst);
2243 }
2244 const uint32_t l = bits(machInst, 20);
2245 const uint32_t c = bits(machInst, 8);
2246 const uint32_t a = bits(machInst, 23, 21);
2247 const uint32_t q = bits(machInst, 6, 5);
2221 if (l == 0 && c == 0) {
2222 if (a == 0) {
2223 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2224 bits(machInst, 7);
2225 const IntRegIndex rt =
2226 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2227 if (bits(machInst, 20) == 1) {
2228 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);

--- 596 unchanged lines hidden ---
2248 if (l == 0 && c == 0) {
2249 if (a == 0) {
2250 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2251 bits(machInst, 7);
2252 const IntRegIndex rt =
2253 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2254 if (bits(machInst, 20) == 1) {
2255 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);

--- 596 unchanged lines hidden ---