Revision c2bc0e38 target-sparc/translate.c
b/target-sparc/translate.c | ||
---|---|---|
3945 | 3945 |
{ |
3946 | 3946 |
unsigned int xop = GET_FIELD(insn, 7, 12); |
3947 | 3947 |
|
3948 |
save_state(dc, cpu_cond); |
|
3949 | 3948 |
cpu_src1 = get_src1(insn, cpu_src1); |
3950 | 3949 |
if (xop == 0x3c || xop == 0x3e) |
3951 | 3950 |
{ |
... | ... | |
3968 | 3967 |
(xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) { |
3969 | 3968 |
switch (xop) { |
3970 | 3969 |
case 0x0: /* load unsigned word */ |
3971 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); |
|
3972 | 3970 |
ABI32_MASK(cpu_addr); |
3973 | 3971 |
tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx); |
3974 | 3972 |
break; |
... | ... | |
3977 | 3975 |
tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx); |
3978 | 3976 |
break; |
3979 | 3977 |
case 0x2: /* load unsigned halfword */ |
3980 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1)); |
|
3981 | 3978 |
ABI32_MASK(cpu_addr); |
3982 | 3979 |
tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx); |
3983 | 3980 |
break; |
... | ... | |
3985 | 3982 |
if (rd & 1) |
3986 | 3983 |
goto illegal_insn; |
3987 | 3984 |
else { |
3988 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); |
|
3985 |
save_state(dc, cpu_cond); |
|
3986 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, |
|
3987 |
tcg_const_i32(7)); // XXX remove |
|
3989 | 3988 |
ABI32_MASK(cpu_addr); |
3990 | 3989 |
tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx); |
3991 | 3990 |
tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64); |
... | ... | |
4001 | 4000 |
tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx); |
4002 | 4001 |
break; |
4003 | 4002 |
case 0xa: /* load signed halfword */ |
4004 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1)); |
|
4005 | 4003 |
ABI32_MASK(cpu_addr); |
4006 | 4004 |
tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx); |
4007 | 4005 |
break; |
... | ... | |
4012 | 4010 |
break; |
4013 | 4011 |
case 0x0f: /* swap register with memory. Also atomically */ |
4014 | 4012 |
CHECK_IU_FEATURE(dc, SWAP); |
4015 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); |
|
4016 | 4013 |
gen_movl_reg_TN(rd, cpu_val); |
4017 | 4014 |
ABI32_MASK(cpu_addr); |
4018 | 4015 |
tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); |
... | ... | |
4027 | 4024 |
if (!supervisor(dc)) |
4028 | 4025 |
goto priv_insn; |
4029 | 4026 |
#endif |
4030 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
|
|
4027 |
save_state(dc, cpu_cond);
|
|
4031 | 4028 |
gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0); |
4032 | 4029 |
break; |
4033 | 4030 |
case 0x11: /* load unsigned byte alternate */ |
... | ... | |
4037 | 4034 |
if (!supervisor(dc)) |
4038 | 4035 |
goto priv_insn; |
4039 | 4036 |
#endif |
4037 |
save_state(dc, cpu_cond); |
|
4040 | 4038 |
gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0); |
4041 | 4039 |
break; |
4042 | 4040 |
case 0x12: /* load unsigned halfword alternate */ |
... | ... | |
4046 | 4044 |
if (!supervisor(dc)) |
4047 | 4045 |
goto priv_insn; |
4048 | 4046 |
#endif |
4049 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
|
|
4047 |
save_state(dc, cpu_cond);
|
|
4050 | 4048 |
gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0); |
4051 | 4049 |
break; |
4052 | 4050 |
case 0x13: /* load double word alternate */ |
... | ... | |
4058 | 4056 |
#endif |
4059 | 4057 |
if (rd & 1) |
4060 | 4058 |
goto illegal_insn; |
4061 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
|
|
4059 |
save_state(dc, cpu_cond);
|
|
4062 | 4060 |
gen_ldda_asi(cpu_tmp0, cpu_val, cpu_addr, insn); |
4063 | 4061 |
gen_movl_TN_reg(rd + 1, cpu_tmp0); |
4064 | 4062 |
break; |
... | ... | |
4069 | 4067 |
if (!supervisor(dc)) |
4070 | 4068 |
goto priv_insn; |
4071 | 4069 |
#endif |
4070 |
save_state(dc, cpu_cond); |
|
4072 | 4071 |
gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1); |
4073 | 4072 |
break; |
4074 | 4073 |
case 0x1a: /* load signed halfword alternate */ |
... | ... | |
4078 | 4077 |
if (!supervisor(dc)) |
4079 | 4078 |
goto priv_insn; |
4080 | 4079 |
#endif |
4081 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
|
|
4080 |
save_state(dc, cpu_cond);
|
|
4082 | 4081 |
gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1); |
4083 | 4082 |
break; |
4084 | 4083 |
case 0x1d: /* ldstuba -- XXX: should be atomically */ |
... | ... | |
4088 | 4087 |
if (!supervisor(dc)) |
4089 | 4088 |
goto priv_insn; |
4090 | 4089 |
#endif |
4090 |
save_state(dc, cpu_cond); |
|
4091 | 4091 |
gen_ldstub_asi(cpu_val, cpu_addr, insn); |
4092 | 4092 |
break; |
4093 | 4093 |
case 0x1f: /* swap reg with alt. memory. Also atomically */ |
... | ... | |
4098 | 4098 |
if (!supervisor(dc)) |
4099 | 4099 |
goto priv_insn; |
4100 | 4100 |
#endif |
4101 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
|
|
4101 |
save_state(dc, cpu_cond);
|
|
4102 | 4102 |
gen_movl_reg_TN(rd, cpu_val); |
4103 | 4103 |
gen_swap_asi(cpu_val, cpu_addr, insn); |
4104 | 4104 |
break; |
... | ... | |
4112 | 4112 |
#endif |
4113 | 4113 |
#ifdef TARGET_SPARC64 |
4114 | 4114 |
case 0x08: /* V9 ldsw */ |
4115 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); |
|
4116 | 4115 |
ABI32_MASK(cpu_addr); |
4117 | 4116 |
tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx); |
4118 | 4117 |
break; |
4119 | 4118 |
case 0x0b: /* V9 ldx */ |
4120 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); |
|
4121 | 4119 |
ABI32_MASK(cpu_addr); |
4122 | 4120 |
tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx); |
4123 | 4121 |
break; |
4124 | 4122 |
case 0x18: /* V9 ldswa */ |
4125 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
|
|
4123 |
save_state(dc, cpu_cond);
|
|
4126 | 4124 |
gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1); |
4127 | 4125 |
break; |
4128 | 4126 |
case 0x1b: /* V9 ldxa */ |
4129 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
|
|
4127 |
save_state(dc, cpu_cond);
|
|
4130 | 4128 |
gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0); |
4131 | 4129 |
break; |
4132 | 4130 |
case 0x2d: /* V9 prefetch, no effect */ |
4133 | 4131 |
goto skip_move; |
4134 | 4132 |
case 0x30: /* V9 ldfa */ |
4135 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
|
|
4133 |
save_state(dc, cpu_cond);
|
|
4136 | 4134 |
gen_ldf_asi(cpu_addr, insn, 4, rd); |
4137 | 4135 |
goto skip_move; |
4138 | 4136 |
case 0x33: /* V9 lddfa */ |
4139 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
|
|
4137 |
save_state(dc, cpu_cond);
|
|
4140 | 4138 |
gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd)); |
4141 | 4139 |
goto skip_move; |
4142 | 4140 |
case 0x3d: /* V9 prefetcha, no effect */ |
4143 | 4141 |
goto skip_move; |
4144 | 4142 |
case 0x32: /* V9 ldqfa */ |
4145 | 4143 |
CHECK_FPU_FEATURE(dc, FLOAT128); |
4146 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
|
|
4144 |
save_state(dc, cpu_cond);
|
|
4147 | 4145 |
gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd)); |
4148 | 4146 |
goto skip_move; |
4149 | 4147 |
#endif |
... | ... | |
4157 | 4155 |
} else if (xop >= 0x20 && xop < 0x24) { |
4158 | 4156 |
if (gen_trap_ifnofpu(dc, cpu_cond)) |
4159 | 4157 |
goto jmp_insn; |
4158 |
save_state(dc, cpu_cond); |
|
4160 | 4159 |
switch (xop) { |
4161 | 4160 |
case 0x20: /* load fpreg */ |
4162 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
|
|
4161 |
ABI32_MASK(cpu_addr);
|
|
4163 | 4162 |
tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); |
4164 | 4163 |
tcg_gen_st_i32(cpu_tmp32, cpu_env, |
4165 | 4164 |
offsetof(CPUState, fpr[rd])); |
4166 | 4165 |
break; |
4167 | 4166 |
case 0x21: /* load fsr */ |
4168 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
|
|
4167 |
ABI32_MASK(cpu_addr);
|
|
4169 | 4168 |
tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); |
4170 | 4169 |
tcg_gen_st_i32(cpu_tmp32, cpu_env, |
4171 | 4170 |
offsetof(CPUState, ft0)); |
... | ... | |
4173 | 4172 |
break; |
4174 | 4173 |
case 0x22: /* load quad fpreg */ |
4175 | 4174 |
CHECK_FPU_FEATURE(dc, FLOAT128); |
4176 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, |
|
4177 |
tcg_const_i32(7)); |
|
4178 | 4175 |
tcg_gen_helper_0_2(helper_ldqf, cpu_addr, dc->mem_idx); |
4179 | 4176 |
gen_op_store_QT0_fpr(QFPREG(rd)); |
4180 | 4177 |
break; |
4181 | 4178 |
case 0x23: /* load double fpreg */ |
4182 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, |
|
4183 |
tcg_const_i32(7)); |
|
4184 | 4179 |
tcg_gen_helper_0_2(helper_lddf, cpu_addr, |
4185 | 4180 |
tcg_const_i32(dc->mem_idx)); |
4186 | 4181 |
gen_op_store_DT0_fpr(DFPREG(rd)); |
... | ... | |
4193 | 4188 |
gen_movl_reg_TN(rd, cpu_val); |
4194 | 4189 |
switch (xop) { |
4195 | 4190 |
case 0x4: /* store word */ |
4196 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); |
|
4197 | 4191 |
ABI32_MASK(cpu_addr); |
4198 | 4192 |
tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx); |
4199 | 4193 |
break; |
... | ... | |
4202 | 4196 |
tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx); |
4203 | 4197 |
break; |
4204 | 4198 |
case 0x6: /* store halfword */ |
4205 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1)); |
|
4206 | 4199 |
ABI32_MASK(cpu_addr); |
4207 | 4200 |
tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx); |
4208 | 4201 |
break; |
... | ... | |
4212 | 4205 |
else { |
4213 | 4206 |
TCGv r_low; |
4214 | 4207 |
|
4215 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); |
|
4208 |
save_state(dc, cpu_cond); |
|
4209 |
ABI32_MASK(cpu_addr); |
|
4210 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, |
|
4211 |
tcg_const_i32(7)); // XXX remove |
|
4216 | 4212 |
r_low = tcg_temp_new(TCG_TYPE_I32); |
4217 | 4213 |
gen_movl_reg_TN(rd + 1, r_low); |
4218 | 4214 |
tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_val, |
... | ... | |
4228 | 4224 |
if (!supervisor(dc)) |
4229 | 4225 |
goto priv_insn; |
4230 | 4226 |
#endif |
4231 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
|
|
4227 |
save_state(dc, cpu_cond);
|
|
4232 | 4228 |
gen_st_asi(cpu_val, cpu_addr, insn, 4); |
4233 | 4229 |
break; |
4234 | 4230 |
case 0x15: /* store byte alternate */ |
... | ... | |
4238 | 4234 |
if (!supervisor(dc)) |
4239 | 4235 |
goto priv_insn; |
4240 | 4236 |
#endif |
4237 |
save_state(dc, cpu_cond); |
|
4241 | 4238 |
gen_st_asi(cpu_val, cpu_addr, insn, 1); |
4242 | 4239 |
break; |
4243 | 4240 |
case 0x16: /* store halfword alternate */ |
... | ... | |
4247 | 4244 |
if (!supervisor(dc)) |
4248 | 4245 |
goto priv_insn; |
4249 | 4246 |
#endif |
4250 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
|
|
4247 |
save_state(dc, cpu_cond);
|
|
4251 | 4248 |
gen_st_asi(cpu_val, cpu_addr, insn, 2); |
4252 | 4249 |
break; |
4253 | 4250 |
case 0x17: /* store double word alternate */ |
... | ... | |
4260 | 4257 |
if (rd & 1) |
4261 | 4258 |
goto illegal_insn; |
4262 | 4259 |
else { |
4263 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
|
|
4260 |
save_state(dc, cpu_cond);
|
|
4264 | 4261 |
gen_stda_asi(cpu_val, cpu_addr, insn, rd); |
4265 | 4262 |
} |
4266 | 4263 |
break; |
4267 | 4264 |
#endif |
4268 | 4265 |
#ifdef TARGET_SPARC64 |
4269 | 4266 |
case 0x0e: /* V9 stx */ |
4270 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); |
|
4271 | 4267 |
ABI32_MASK(cpu_addr); |
4272 | 4268 |
tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx); |
4273 | 4269 |
break; |
4274 | 4270 |
case 0x1e: /* V9 stxa */ |
4275 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
|
|
4271 |
save_state(dc, cpu_cond);
|
|
4276 | 4272 |
gen_st_asi(cpu_val, cpu_addr, insn, 8); |
4277 | 4273 |
break; |
4278 | 4274 |
#endif |
... | ... | |
4282 | 4278 |
} else if (xop > 0x23 && xop < 0x28) { |
4283 | 4279 |
if (gen_trap_ifnofpu(dc, cpu_cond)) |
4284 | 4280 |
goto jmp_insn; |
4281 |
save_state(dc, cpu_cond); |
|
4285 | 4282 |
switch (xop) { |
4286 | 4283 |
case 0x24: /* store fpreg */ |
4287 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
|
|
4284 |
ABI32_MASK(cpu_addr);
|
|
4288 | 4285 |
tcg_gen_ld_i32(cpu_tmp32, cpu_env, |
4289 | 4286 |
offsetof(CPUState, fpr[rd])); |
4290 | 4287 |
tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); |
4291 | 4288 |
break; |
4292 | 4289 |
case 0x25: /* stfsr, V9 stxfsr */ |
4293 |
#ifdef CONFIG_USER_ONLY |
|
4294 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); |
|
4295 |
#endif |
|
4290 |
ABI32_MASK(cpu_addr); |
|
4296 | 4291 |
tcg_gen_helper_0_0(helper_stfsr); |
4297 | 4292 |
tcg_gen_ld_i32(cpu_tmp32, cpu_env, |
4298 | 4293 |
offsetof(CPUState, ft0)); |
... | ... | |
4302 | 4297 |
#ifdef TARGET_SPARC64 |
4303 | 4298 |
/* V9 stqf, store quad fpreg */ |
4304 | 4299 |
CHECK_FPU_FEATURE(dc, FLOAT128); |
4305 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, |
|
4306 |
tcg_const_i32(7)); |
|
4307 | 4300 |
gen_op_load_fpr_QT0(QFPREG(rd)); |
4308 | 4301 |
tcg_gen_helper_0_2(helper_stqf, cpu_addr, dc->mem_idx); |
4309 | 4302 |
break; |
... | ... | |
4320 | 4313 |
#endif |
4321 | 4314 |
#endif |
4322 | 4315 |
case 0x27: /* store double fpreg */ |
4323 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, |
|
4324 |
tcg_const_i32(7)); |
|
4325 | 4316 |
gen_op_load_fpr_DT0(DFPREG(rd)); |
4326 | 4317 |
tcg_gen_helper_0_2(helper_stdf, cpu_addr, |
4327 | 4318 |
tcg_const_i32(dc->mem_idx)); |
... | ... | |
4330 | 4321 |
goto illegal_insn; |
4331 | 4322 |
} |
4332 | 4323 |
} else if (xop > 0x33 && xop < 0x3f) { |
4324 |
save_state(dc, cpu_cond); |
|
4333 | 4325 |
switch (xop) { |
4334 | 4326 |
#ifdef TARGET_SPARC64 |
4335 | 4327 |
case 0x34: /* V9 stfa */ |
4336 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); |
|
4337 | 4328 |
gen_op_load_fpr_FT0(rd); |
4338 | 4329 |
gen_stf_asi(cpu_addr, insn, 4, rd); |
4339 | 4330 |
break; |
... | ... | |
4345 | 4336 |
gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd)); |
4346 | 4337 |
break; |
4347 | 4338 |
case 0x37: /* V9 stdfa */ |
4348 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); |
|
4349 | 4339 |
gen_op_load_fpr_DT0(DFPREG(rd)); |
4350 | 4340 |
gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd)); |
4351 | 4341 |
break; |
4352 | 4342 |
case 0x3c: /* V9 casa */ |
4353 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3)); |
|
4354 | 4343 |
gen_cas_asi(cpu_val, cpu_addr, cpu_val, insn, rd); |
4355 | 4344 |
gen_movl_TN_reg(rd, cpu_val); |
4356 | 4345 |
break; |
4357 | 4346 |
case 0x3e: /* V9 casxa */ |
4358 |
tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7)); |
|
4359 | 4347 |
gen_casx_asi(cpu_val, cpu_addr, cpu_val, insn, rd); |
4360 | 4348 |
gen_movl_TN_reg(rd, cpu_val); |
4361 | 4349 |
break; |
Also available in: Unified diff