|
|
|
@ -1764,7 +1764,7 @@ static DisasASI resolve_asi(DisasContext *dc, int asi, MemOp memop) |
|
|
|
case ASI_FL16_SL: |
|
|
|
case ASI_FL16_P: |
|
|
|
case ASI_FL16_PL: |
|
|
|
memop = MO_TEUW; |
|
|
|
memop = MO_BEUW; |
|
|
|
type = GET_ASI_SHORT; |
|
|
|
break; |
|
|
|
} |
|
|
|
@ -2215,7 +2215,7 @@ static void gen_ldda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd) |
|
|
|
* byte swapped. We perform one 128-bit LE load, so must swap |
|
|
|
* the order of the writebacks. |
|
|
|
*/ |
|
|
|
if ((mop & MO_BSWAP) == MO_TE) { |
|
|
|
if ((mop & MO_BSWAP) == MO_BE) { |
|
|
|
tcg_gen_extr_i128_i64(lo, hi, t); |
|
|
|
} else { |
|
|
|
tcg_gen_extr_i128_i64(hi, lo, t); |
|
|
|
@ -2235,7 +2235,7 @@ static void gen_ldda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd) |
|
|
|
/* Note that LE ldda acts as if each 32-bit register
|
|
|
|
result is byte swapped. Having just performed one |
|
|
|
64-bit bswap, we need now to swap the writebacks. */ |
|
|
|
if ((da->memop & MO_BSWAP) == MO_TE) { |
|
|
|
if ((da->memop & MO_BSWAP) == MO_BE) { |
|
|
|
tcg_gen_extr_i64_tl(lo, hi, tmp); |
|
|
|
} else { |
|
|
|
tcg_gen_extr_i64_tl(hi, lo, tmp); |
|
|
|
@ -2252,7 +2252,7 @@ static void gen_ldda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd) |
|
|
|
gen_helper_ld_code(tmp, tcg_env, addr, tcg_constant_i32(oi)); |
|
|
|
|
|
|
|
/* See above. */ |
|
|
|
if ((da->memop & MO_BSWAP) == MO_TE) { |
|
|
|
if ((da->memop & MO_BSWAP) == MO_BE) { |
|
|
|
tcg_gen_extr_i64_tl(lo, hi, tmp); |
|
|
|
} else { |
|
|
|
tcg_gen_extr_i64_tl(hi, lo, tmp); |
|
|
|
@ -2277,7 +2277,7 @@ static void gen_ldda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd) |
|
|
|
gen_helper_ld_asi(tmp, tcg_env, addr, r_asi, r_mop); |
|
|
|
|
|
|
|
/* See above. */ |
|
|
|
if ((da->memop & MO_BSWAP) == MO_TE) { |
|
|
|
if ((da->memop & MO_BSWAP) == MO_BE) { |
|
|
|
tcg_gen_extr_i64_tl(lo, hi, tmp); |
|
|
|
} else { |
|
|
|
tcg_gen_extr_i64_tl(hi, lo, tmp); |
|
|
|
@ -2310,7 +2310,7 @@ static void gen_stda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd) |
|
|
|
* byte swapped. We perform one 128-bit LE store, so must swap |
|
|
|
* the order of the construction. |
|
|
|
*/ |
|
|
|
if ((mop & MO_BSWAP) == MO_TE) { |
|
|
|
if ((mop & MO_BSWAP) == MO_BE) { |
|
|
|
tcg_gen_concat_i64_i128(t, lo, hi); |
|
|
|
} else { |
|
|
|
tcg_gen_concat_i64_i128(t, hi, lo); |
|
|
|
@ -2329,7 +2329,7 @@ static void gen_stda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd) |
|
|
|
/* Note that LE stda acts as if each 32-bit register result is
|
|
|
|
byte swapped. We will perform one 64-bit LE store, so now |
|
|
|
we must swap the order of the construction. */ |
|
|
|
if ((da->memop & MO_BSWAP) == MO_TE) { |
|
|
|
if ((da->memop & MO_BSWAP) == MO_BE) { |
|
|
|
tcg_gen_concat_tl_i64(t64, lo, hi); |
|
|
|
} else { |
|
|
|
tcg_gen_concat_tl_i64(t64, hi, lo); |
|
|
|
@ -2345,7 +2345,7 @@ static void gen_stda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd) |
|
|
|
* See comments for GET_ASI_COPY above. |
|
|
|
*/ |
|
|
|
{ |
|
|
|
MemOp mop = MO_TE | MO_128 | MO_ATOM_IFALIGN_PAIR; |
|
|
|
MemOp mop = MO_BE | MO_128 | MO_ATOM_IFALIGN_PAIR; |
|
|
|
TCGv_i64 t8 = tcg_temp_new_i64(); |
|
|
|
TCGv_i128 t16 = tcg_temp_new_i128(); |
|
|
|
TCGv daddr = tcg_temp_new(); |
|
|
|
@ -2368,7 +2368,7 @@ static void gen_stda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd) |
|
|
|
TCGv_i64 t64 = tcg_temp_new_i64(); |
|
|
|
|
|
|
|
/* See above. */ |
|
|
|
if ((da->memop & MO_BSWAP) == MO_TE) { |
|
|
|
if ((da->memop & MO_BSWAP) == MO_BE) { |
|
|
|
tcg_gen_concat_tl_i64(t64, lo, hi); |
|
|
|
} else { |
|
|
|
tcg_gen_concat_tl_i64(t64, hi, lo); |
|
|
|
@ -4428,13 +4428,13 @@ static bool do_ld_gpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop) |
|
|
|
return advance_pc(dc); |
|
|
|
} |
|
|
|
|
|
|
|
TRANS(LDUW, ALL, do_ld_gpr, a, MO_TEUL) |
|
|
|
TRANS(LDUW, ALL, do_ld_gpr, a, MO_BEUL) |
|
|
|
TRANS(LDUB, ALL, do_ld_gpr, a, MO_UB) |
|
|
|
TRANS(LDUH, ALL, do_ld_gpr, a, MO_TEUW) |
|
|
|
TRANS(LDUH, ALL, do_ld_gpr, a, MO_BEUW) |
|
|
|
TRANS(LDSB, ALL, do_ld_gpr, a, MO_SB) |
|
|
|
TRANS(LDSH, ALL, do_ld_gpr, a, MO_TESW) |
|
|
|
TRANS(LDSW, 64, do_ld_gpr, a, MO_TESL) |
|
|
|
TRANS(LDX, 64, do_ld_gpr, a, MO_TEUQ) |
|
|
|
TRANS(LDSH, ALL, do_ld_gpr, a, MO_BESW) |
|
|
|
TRANS(LDSW, 64, do_ld_gpr, a, MO_BESL) |
|
|
|
TRANS(LDX, 64, do_ld_gpr, a, MO_BEUQ) |
|
|
|
|
|
|
|
static bool do_st_gpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop) |
|
|
|
{ |
|
|
|
@ -4451,10 +4451,10 @@ static bool do_st_gpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop) |
|
|
|
return advance_pc(dc); |
|
|
|
} |
|
|
|
|
|
|
|
TRANS(STW, ALL, do_st_gpr, a, MO_TEUL) |
|
|
|
TRANS(STW, ALL, do_st_gpr, a, MO_BEUL) |
|
|
|
TRANS(STB, ALL, do_st_gpr, a, MO_UB) |
|
|
|
TRANS(STH, ALL, do_st_gpr, a, MO_TEUW) |
|
|
|
TRANS(STX, 64, do_st_gpr, a, MO_TEUQ) |
|
|
|
TRANS(STH, ALL, do_st_gpr, a, MO_BEUW) |
|
|
|
TRANS(STX, 64, do_st_gpr, a, MO_BEUQ) |
|
|
|
|
|
|
|
static bool trans_LDD(DisasContext *dc, arg_r_r_ri_asi *a) |
|
|
|
{ |
|
|
|
@ -4468,7 +4468,7 @@ static bool trans_LDD(DisasContext *dc, arg_r_r_ri_asi *a) |
|
|
|
if (addr == NULL) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
da = resolve_asi(dc, a->asi, MO_TEUQ); |
|
|
|
da = resolve_asi(dc, a->asi, MO_BEUQ); |
|
|
|
gen_ldda_asi(dc, &da, addr, a->rd); |
|
|
|
return advance_pc(dc); |
|
|
|
} |
|
|
|
@ -4485,7 +4485,7 @@ static bool trans_STD(DisasContext *dc, arg_r_r_ri_asi *a) |
|
|
|
if (addr == NULL) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
da = resolve_asi(dc, a->asi, MO_TEUQ); |
|
|
|
da = resolve_asi(dc, a->asi, MO_BEUQ); |
|
|
|
gen_stda_asi(dc, &da, addr, a->rd); |
|
|
|
return advance_pc(dc); |
|
|
|
} |
|
|
|
@ -4516,7 +4516,7 @@ static bool trans_SWAP(DisasContext *dc, arg_r_r_ri_asi *a) |
|
|
|
if (addr == NULL) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
da = resolve_asi(dc, a->asi, MO_TEUL); |
|
|
|
da = resolve_asi(dc, a->asi, MO_BEUL); |
|
|
|
|
|
|
|
dst = gen_dest_gpr(dc, a->rd); |
|
|
|
src = gen_load_gpr(dc, a->rd); |
|
|
|
@ -4544,8 +4544,8 @@ static bool do_casa(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop) |
|
|
|
return advance_pc(dc); |
|
|
|
} |
|
|
|
|
|
|
|
TRANS(CASA, CASA, do_casa, a, MO_TEUL) |
|
|
|
TRANS(CASXA, 64, do_casa, a, MO_TEUQ) |
|
|
|
TRANS(CASA, CASA, do_casa, a, MO_BEUL) |
|
|
|
TRANS(CASXA, 64, do_casa, a, MO_BEUQ) |
|
|
|
|
|
|
|
static bool do_ld_fpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp sz) |
|
|
|
{ |
|
|
|
@ -4561,7 +4561,7 @@ static bool do_ld_fpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp sz) |
|
|
|
if (sz == MO_128 && gen_trap_float128(dc)) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
da = resolve_asi(dc, a->asi, MO_TE | sz); |
|
|
|
da = resolve_asi(dc, a->asi, MO_BE | sz); |
|
|
|
gen_ldf_asi(dc, &da, sz, addr, a->rd); |
|
|
|
gen_update_fprs_dirty(dc, a->rd); |
|
|
|
return advance_pc(dc); |
|
|
|
@ -4590,7 +4590,7 @@ static bool do_st_fpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp sz) |
|
|
|
if (sz == MO_128 && gen_trap_float128(dc)) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
da = resolve_asi(dc, a->asi, MO_TE | sz); |
|
|
|
da = resolve_asi(dc, a->asi, MO_BE | sz); |
|
|
|
gen_stf_asi(dc, &da, sz, addr, a->rd); |
|
|
|
return advance_pc(dc); |
|
|
|
} |
|
|
|
@ -4629,7 +4629,7 @@ static bool trans_STDFQ(DisasContext *dc, arg_STDFQ *a) |
|
|
|
/* Store the single element from the queue. */ |
|
|
|
TCGv_i64 fq = tcg_temp_new_i64(); |
|
|
|
tcg_gen_ld_i64(fq, tcg_env, offsetof(CPUSPARCState, fq.d)); |
|
|
|
tcg_gen_qemu_st_i64(fq, addr, dc->mem_idx, MO_TEUQ | MO_ALIGN_4); |
|
|
|
tcg_gen_qemu_st_i64(fq, addr, dc->mem_idx, MO_BEUQ | MO_ALIGN_4); |
|
|
|
|
|
|
|
/* Mark the queue empty, transitioning to fp_execute state. */ |
|
|
|
tcg_gen_st_i32(tcg_constant_i32(0), tcg_env, |
|
|
|
@ -4655,7 +4655,7 @@ static bool trans_LDFSR(DisasContext *dc, arg_r_r_ri *a) |
|
|
|
} |
|
|
|
|
|
|
|
tmp = tcg_temp_new_i32(); |
|
|
|
tcg_gen_qemu_ld_i32(tmp, addr, dc->mem_idx, MO_TEUL | MO_ALIGN); |
|
|
|
tcg_gen_qemu_ld_i32(tmp, addr, dc->mem_idx, MO_BEUL | MO_ALIGN); |
|
|
|
|
|
|
|
tcg_gen_extract_i32(cpu_fcc[0], tmp, FSR_FCC0_SHIFT, 2); |
|
|
|
/* LDFSR does not change FCC[1-3]. */ |
|
|
|
@ -4679,7 +4679,7 @@ static bool do_ldxfsr(DisasContext *dc, arg_r_r_ri *a, bool entire) |
|
|
|
} |
|
|
|
|
|
|
|
t64 = tcg_temp_new_i64(); |
|
|
|
tcg_gen_qemu_ld_i64(t64, addr, dc->mem_idx, MO_TEUQ | MO_ALIGN); |
|
|
|
tcg_gen_qemu_ld_i64(t64, addr, dc->mem_idx, MO_BEUQ | MO_ALIGN); |
|
|
|
|
|
|
|
lo = tcg_temp_new_i32(); |
|
|
|
hi = cpu_fcc[3]; |
|
|
|
@ -4722,8 +4722,8 @@ static bool do_stfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop) |
|
|
|
return advance_pc(dc); |
|
|
|
} |
|
|
|
|
|
|
|
TRANS(STFSR, ALL, do_stfsr, a, MO_TEUL) |
|
|
|
TRANS(STXFSR, 64, do_stfsr, a, MO_TEUQ) |
|
|
|
TRANS(STFSR, ALL, do_stfsr, a, MO_BEUL) |
|
|
|
TRANS(STXFSR, 64, do_stfsr, a, MO_BEUQ) |
|
|
|
|
|
|
|
static bool do_fc(DisasContext *dc, int rd, int32_t c) |
|
|
|
{ |
|
|
|
|