Revision 6c073553
b/target-sparc/translate.c | ||
---|---|---|
2221 | 2221 |
|
2222 | 2222 |
tcg_temp_free_i32(r_tl); |
2223 | 2223 |
} |
2224 |
|
|
2225 |
static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2, |
|
2226 |
int width, bool cc, bool left) |
|
2227 |
{ |
|
2228 |
TCGv lo1, lo2, t1, t2; |
|
2229 |
uint64_t amask, tabl, tabr; |
|
2230 |
int shift, imask, omask; |
|
2231 |
|
|
2232 |
if (cc) { |
|
2233 |
tcg_gen_mov_tl(cpu_cc_src, s1); |
|
2234 |
tcg_gen_mov_tl(cpu_cc_src2, s2); |
|
2235 |
tcg_gen_sub_tl(cpu_cc_dst, s1, s2); |
|
2236 |
tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB); |
|
2237 |
dc->cc_op = CC_OP_SUB; |
|
2238 |
} |
|
2239 |
|
|
2240 |
/* Theory of operation: there are two tables, left and right (not to |
|
2241 |
be confused with the left and right versions of the opcode). These |
|
2242 |
are indexed by the low 3 bits of the inputs. To make things "easy", |
|
2243 |
these tables are loaded into two constants, TABL and TABR below. |
|
2244 |
The operation index = (input & imask) << shift calculates the index |
|
2245 |
into the constant, while val = (table >> index) & omask calculates |
|
2246 |
the value we're looking for. */ |
|
2247 |
switch (width) { |
|
2248 |
case 8: |
|
2249 |
imask = 0x7; |
|
2250 |
shift = 3; |
|
2251 |
omask = 0xff; |
|
2252 |
if (left) { |
|
2253 |
tabl = 0x80c0e0f0f8fcfeffULL; |
|
2254 |
tabr = 0xff7f3f1f0f070301ULL; |
|
2255 |
} else { |
|
2256 |
tabl = 0x0103070f1f3f7fffULL; |
|
2257 |
tabr = 0xfffefcf8f0e0c080ULL; |
|
2258 |
} |
|
2259 |
break; |
|
2260 |
case 16: |
|
2261 |
imask = 0x6; |
|
2262 |
shift = 1; |
|
2263 |
omask = 0xf; |
|
2264 |
if (left) { |
|
2265 |
tabl = 0x8cef; |
|
2266 |
tabr = 0xf731; |
|
2267 |
} else { |
|
2268 |
tabl = 0x137f; |
|
2269 |
tabr = 0xfec8; |
|
2270 |
} |
|
2271 |
break; |
|
2272 |
case 32: |
|
2273 |
imask = 0x4; |
|
2274 |
shift = 0; |
|
2275 |
omask = 0x3; |
|
2276 |
if (left) { |
|
2277 |
tabl = (2 << 2) | 3; |
|
2278 |
tabr = (3 << 2) | 1; |
|
2279 |
} else { |
|
2280 |
tabl = (1 << 2) | 3; |
|
2281 |
tabr = (3 << 2) | 2; |
|
2282 |
} |
|
2283 |
break; |
|
2284 |
default: |
|
2285 |
abort(); |
|
2286 |
} |
|
2287 |
|
|
2288 |
lo1 = tcg_temp_new(); |
|
2289 |
lo2 = tcg_temp_new(); |
|
2290 |
tcg_gen_andi_tl(lo1, s1, imask); |
|
2291 |
tcg_gen_andi_tl(lo2, s2, imask); |
|
2292 |
tcg_gen_shli_tl(lo1, lo1, shift); |
|
2293 |
tcg_gen_shli_tl(lo2, lo2, shift); |
|
2294 |
|
|
2295 |
t1 = tcg_const_tl(tabl); |
|
2296 |
t2 = tcg_const_tl(tabr); |
|
2297 |
tcg_gen_shr_tl(lo1, t1, lo1); |
|
2298 |
tcg_gen_shr_tl(lo2, t2, lo2); |
|
2299 |
tcg_gen_andi_tl(dst, lo1, omask); |
|
2300 |
tcg_gen_andi_tl(lo2, lo2, omask); |
|
2301 |
|
|
2302 |
amask = -8; |
|
2303 |
if (AM_CHECK(dc)) { |
|
2304 |
amask &= 0xffffffffULL; |
|
2305 |
} |
|
2306 |
tcg_gen_andi_tl(s1, s1, amask); |
|
2307 |
tcg_gen_andi_tl(s2, s2, amask); |
|
2308 |
|
|
2309 |
/* We want to compute |
|
2310 |
dst = (s1 == s2 ? lo1 : lo1 & lo2). |
|
2311 |
We've already done dst = lo1, so this reduces to |
|
2312 |
dst &= (s1 == s2 ? -1 : lo2) |
|
2313 |
Which we perform by |
|
2314 |
lo2 |= -(s1 == s2) |
|
2315 |
dst &= lo2 |
|
2316 |
*/ |
|
2317 |
tcg_gen_setcond_tl(TCG_COND_EQ, t1, s1, s2); |
|
2318 |
tcg_gen_neg_tl(t1, t1); |
|
2319 |
tcg_gen_or_tl(lo2, lo2, t1); |
|
2320 |
tcg_gen_and_tl(dst, dst, lo2); |
|
2321 |
|
|
2322 |
tcg_temp_free(lo1); |
|
2323 |
tcg_temp_free(lo2); |
|
2324 |
tcg_temp_free(t1); |
|
2325 |
tcg_temp_free(t2); |
|
2326 |
} |
|
2224 | 2327 |
#endif |
2225 | 2328 |
|
2226 | 2329 |
#define CHECK_IU_FEATURE(dc, FEATURE) \ |
... | ... | |
3954 | 4057 |
|
3955 | 4058 |
switch (opf) { |
3956 | 4059 |
case 0x000: /* VIS I edge8cc */ |
4060 |
CHECK_FPU_FEATURE(dc, VIS1); |
|
4061 |
gen_movl_reg_TN(rs1, cpu_src1); |
|
4062 |
gen_movl_reg_TN(rs2, cpu_src2); |
|
4063 |
gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 0); |
|
4064 |
gen_movl_TN_reg(rd, cpu_dst); |
|
4065 |
break; |
|
3957 | 4066 |
case 0x001: /* VIS II edge8n */ |
4067 |
CHECK_FPU_FEATURE(dc, VIS2); |
|
4068 |
gen_movl_reg_TN(rs1, cpu_src1); |
|
4069 |
gen_movl_reg_TN(rs2, cpu_src2); |
|
4070 |
gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 0); |
|
4071 |
gen_movl_TN_reg(rd, cpu_dst); |
|
4072 |
break; |
|
3958 | 4073 |
case 0x002: /* VIS I edge8lcc */ |
4074 |
CHECK_FPU_FEATURE(dc, VIS1); |
|
4075 |
gen_movl_reg_TN(rs1, cpu_src1); |
|
4076 |
gen_movl_reg_TN(rs2, cpu_src2); |
|
4077 |
gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 1); |
|
4078 |
gen_movl_TN_reg(rd, cpu_dst); |
|
4079 |
break; |
|
3959 | 4080 |
case 0x003: /* VIS II edge8ln */ |
4081 |
CHECK_FPU_FEATURE(dc, VIS2); |
|
4082 |
gen_movl_reg_TN(rs1, cpu_src1); |
|
4083 |
gen_movl_reg_TN(rs2, cpu_src2); |
|
4084 |
gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 1); |
|
4085 |
gen_movl_TN_reg(rd, cpu_dst); |
|
4086 |
break; |
|
3960 | 4087 |
case 0x004: /* VIS I edge16cc */ |
4088 |
CHECK_FPU_FEATURE(dc, VIS1); |
|
4089 |
gen_movl_reg_TN(rs1, cpu_src1); |
|
4090 |
gen_movl_reg_TN(rs2, cpu_src2); |
|
4091 |
gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 0); |
|
4092 |
gen_movl_TN_reg(rd, cpu_dst); |
|
4093 |
break; |
|
3961 | 4094 |
case 0x005: /* VIS II edge16n */ |
4095 |
CHECK_FPU_FEATURE(dc, VIS2); |
|
4096 |
gen_movl_reg_TN(rs1, cpu_src1); |
|
4097 |
gen_movl_reg_TN(rs2, cpu_src2); |
|
4098 |
gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 0); |
|
4099 |
gen_movl_TN_reg(rd, cpu_dst); |
|
4100 |
break; |
|
3962 | 4101 |
case 0x006: /* VIS I edge16lcc */ |
4102 |
CHECK_FPU_FEATURE(dc, VIS1); |
|
4103 |
gen_movl_reg_TN(rs1, cpu_src1); |
|
4104 |
gen_movl_reg_TN(rs2, cpu_src2); |
|
4105 |
gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 1); |
|
4106 |
gen_movl_TN_reg(rd, cpu_dst); |
|
4107 |
break; |
|
3963 | 4108 |
case 0x007: /* VIS II edge16ln */ |
4109 |
CHECK_FPU_FEATURE(dc, VIS2); |
|
4110 |
gen_movl_reg_TN(rs1, cpu_src1); |
|
4111 |
gen_movl_reg_TN(rs2, cpu_src2); |
|
4112 |
gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 1); |
|
4113 |
gen_movl_TN_reg(rd, cpu_dst); |
|
4114 |
break; |
|
3964 | 4115 |
case 0x008: /* VIS I edge32cc */ |
4116 |
CHECK_FPU_FEATURE(dc, VIS1); |
|
4117 |
gen_movl_reg_TN(rs1, cpu_src1); |
|
4118 |
gen_movl_reg_TN(rs2, cpu_src2); |
|
4119 |
gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 0); |
|
4120 |
gen_movl_TN_reg(rd, cpu_dst); |
|
4121 |
break; |
|
3965 | 4122 |
case 0x009: /* VIS II edge32n */ |
4123 |
CHECK_FPU_FEATURE(dc, VIS2); |
|
4124 |
gen_movl_reg_TN(rs1, cpu_src1); |
|
4125 |
gen_movl_reg_TN(rs2, cpu_src2); |
|
4126 |
gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 0); |
|
4127 |
gen_movl_TN_reg(rd, cpu_dst); |
|
4128 |
break; |
|
3966 | 4129 |
case 0x00a: /* VIS I edge32lcc */ |
4130 |
CHECK_FPU_FEATURE(dc, VIS1); |
|
4131 |
gen_movl_reg_TN(rs1, cpu_src1); |
|
4132 |
gen_movl_reg_TN(rs2, cpu_src2); |
|
4133 |
gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 1); |
|
4134 |
gen_movl_TN_reg(rd, cpu_dst); |
|
4135 |
break; |
|
3967 | 4136 |
case 0x00b: /* VIS II edge32ln */ |
3968 |
// XXX |
|
3969 |
goto illegal_insn; |
|
4137 |
CHECK_FPU_FEATURE(dc, VIS2); |
|
4138 |
gen_movl_reg_TN(rs1, cpu_src1); |
|
4139 |
gen_movl_reg_TN(rs2, cpu_src2); |
|
4140 |
gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 1); |
|
4141 |
gen_movl_TN_reg(rd, cpu_dst); |
|
4142 |
break; |
|
3970 | 4143 |
case 0x010: /* VIS I array8 */ |
3971 | 4144 |
CHECK_FPU_FEATURE(dc, VIS1); |
3972 | 4145 |
cpu_src1 = get_src1(insn, cpu_src1); |
Also available in: Unified diff