Signed-off-by: Richard Henderson <r...@twiddle.net> --- target-tilegx/translate.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c index 210e912..2a0798a 100644 --- a/target-tilegx/translate.c +++ b/target-tilegx/translate.c @@ -180,6 +180,19 @@ static void gen_saturate_op(TCGv tdest, TCGv tsrca, TCGv tsrcb, tcg_temp_free(t0); } +static void gen_atomic_excp(DisasContext *dc, unsigned dest, unsigned srca, + unsigned srcb, TileExcp excp) +{ +#ifdef CONFIG_USER_ONLY + TCGv_i32 t = tcg_const_i32((dest << 16) | (srca << 8) | srcb); + tcg_gen_st_i32(t, cpu_env, offsetof(CPUTLGState, excparam)); + tcg_temp_free_i32(t); + gen_exception(dc, excp); +#else + gen_exception(dc, TILEGX_EXCP_OPCODE_UNIMPLEMENTED); +#endif +} + static void gen_dblaligni(TCGv tdest, TCGv tsrca, TCGv tsrcb, int shr) { TCGv t0 = tcg_temp_new(); @@ -595,8 +608,13 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext, mnemonic = "cmpeq"; break; case OE_RRR(CMPEXCH4, 0, X1): + gen_atomic_excp(dc, dest, srca, srcb, TILEGX_EXCP_OPCODE_CMPEXCH4); + mnemonic = "cmpexch4"; + break; case OE_RRR(CMPEXCH, 0, X1): - return TILEGX_EXCP_OPCODE_UNIMPLEMENTED; + gen_atomic_excp(dc, dest, srca, srcb, TILEGX_EXCP_OPCODE_CMPEXCH); + mnemonic = "cmpexch"; + break; case OE_RRR(CMPLES, 0, X0): case OE_RRR(CMPLES, 0, X1): case OE_RRR(CMPLES, 2, Y0): @@ -662,7 +680,13 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext, mnemonic = "dblalign"; break; case OE_RRR(EXCH4, 0, X1): + gen_atomic_excp(dc, dest, srca, srcb, TILEGX_EXCP_OPCODE_EXCH4); + mnemonic = "exch4"; + break; case OE_RRR(EXCH, 0, X1): + gen_atomic_excp(dc, dest, srca, srcb, TILEGX_EXCP_OPCODE_EXCH); + mnemonic = "exch"; + break; case OE_RRR(FDOUBLE_ADDSUB, 0, X0): case OE_RRR(FDOUBLE_ADD_FLAGS, 0, X0): case OE_RRR(FDOUBLE_MUL_FLAGS, 0, X0): @@ -672,13 +696,37 @@ static TileExcp gen_rrr_opcode(DisasContext *dc, unsigned opext, case OE_RRR(FDOUBLE_UNPACK_MAX, 0, X0): case OE_RRR(FDOUBLE_UNPACK_MIN, 0, X0): case OE_RRR(FETCHADD4, 0, X1): + gen_atomic_excp(dc, dest, srca, srcb, TILEGX_EXCP_OPCODE_FETCHADD4); + mnemonic = "fetchadd4"; + break; case OE_RRR(FETCHADDGEZ4, 0, X1): + gen_atomic_excp(dc, dest, srca, srcb, TILEGX_EXCP_OPCODE_FETCHADDGEZ4); + mnemonic = "fetchaddgez4"; + break; case OE_RRR(FETCHADDGEZ, 0, X1): + gen_atomic_excp(dc, dest, srca, srcb, TILEGX_EXCP_OPCODE_FETCHADDGEZ); + mnemonic = "fetchaddgez"; + break; case OE_RRR(FETCHADD, 0, X1): + gen_atomic_excp(dc, dest, srca, srcb, TILEGX_EXCP_OPCODE_FETCHADD); + mnemonic = "fetchadd"; + break; case OE_RRR(FETCHAND4, 0, X1): + gen_atomic_excp(dc, dest, srca, srcb, TILEGX_EXCP_OPCODE_FETCHAND4); + mnemonic = "fetchand4"; + break; case OE_RRR(FETCHAND, 0, X1): + gen_atomic_excp(dc, dest, srca, srcb, TILEGX_EXCP_OPCODE_FETCHAND); + mnemonic = "fetchand"; + break; case OE_RRR(FETCHOR4, 0, X1): + gen_atomic_excp(dc, dest, srca, srcb, TILEGX_EXCP_OPCODE_FETCHOR4); + mnemonic = "fetchor4"; + break; case OE_RRR(FETCHOR, 0, X1): + gen_atomic_excp(dc, dest, srca, srcb, TILEGX_EXCP_OPCODE_FETCHOR); + mnemonic = "fetchor"; + break; case OE_RRR(FSINGLE_ADD1, 0, X0): case OE_RRR(FSINGLE_ADDSUB2, 0, X0): case OE_RRR(FSINGLE_MUL1, 0, X0): -- 2.4.3