mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-07 12:48:02 +00:00
target-tricore: Add instructions of SRR opcode format
Add instructions of SRR opcode format. Add helper for add/sub_ssov. Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Message-id: 1409572800-4116-8-git-send-email-kbastian@mail.uni-paderborn.de Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
0707ec1bea
commit
2692802a37
@ -14,3 +14,7 @@
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Arithmetic */
|
||||
DEF_HELPER_3(add_ssov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
|
||||
|
@ -20,6 +20,49 @@
|
||||
#include "exec/helper-proto.h"
|
||||
#include "exec/cpu_ldst.h"
|
||||
|
||||
#define SSOV(env, ret, arg, len) do { \
|
||||
int64_t max_pos = INT##len ##_MAX; \
|
||||
int64_t max_neg = INT##len ##_MIN; \
|
||||
if (arg > max_pos) { \
|
||||
env->PSW_USB_V = (1 << 31); \
|
||||
env->PSW_USB_SV = (1 << 31); \
|
||||
ret = (target_ulong)max_pos; \
|
||||
} else { \
|
||||
if (arg < max_neg) { \
|
||||
env->PSW_USB_V = (1 << 31); \
|
||||
env->PSW_USB_SV = (1 << 31); \
|
||||
ret = (target_ulong)max_neg; \
|
||||
} else { \
|
||||
env->PSW_USB_V = 0; \
|
||||
ret = (target_ulong)arg; \
|
||||
} \
|
||||
} \
|
||||
env->PSW_USB_AV = arg ^ arg * 2u; \
|
||||
env->PSW_USB_SAV |= env->PSW_USB_AV; \
|
||||
} while (0)
|
||||
|
||||
target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
|
||||
target_ulong r2)
|
||||
{
|
||||
target_ulong ret;
|
||||
int64_t t1 = sextract64(r1, 0, 32);
|
||||
int64_t t2 = sextract64(r2, 0, 32);
|
||||
int64_t result = t1 + t2;
|
||||
SSOV(env, ret, result, 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
|
||||
target_ulong r2)
|
||||
{
|
||||
target_ulong ret;
|
||||
int64_t t1 = sextract64(r1, 0, 32);
|
||||
int64_t t2 = sextract64(r2, 0, 32);
|
||||
int64_t result = t1 - t2;
|
||||
SSOV(env, ret, result, 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
|
||||
uint32_t exception,
|
||||
int error_code,
|
||||
|
@ -187,6 +187,53 @@ static inline void gen_condi_add(TCGCond cond, TCGv r1, int32_t r2,
|
||||
tcg_temp_free(temp);
|
||||
}
|
||||
|
||||
static inline void gen_sub_d(TCGv ret, TCGv r1, TCGv r2)
|
||||
{
|
||||
TCGv temp = tcg_temp_new_i32();
|
||||
TCGv result = tcg_temp_new_i32();
|
||||
|
||||
tcg_gen_sub_tl(result, r1, r2);
|
||||
/* calc V bit */
|
||||
tcg_gen_xor_tl(cpu_PSW_V, result, r1);
|
||||
tcg_gen_xor_tl(temp, r1, r2);
|
||||
tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp);
|
||||
/* calc SV bit */
|
||||
tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
|
||||
/* Calc AV bit */
|
||||
tcg_gen_add_tl(cpu_PSW_AV, result, result);
|
||||
tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
|
||||
/* calc SAV bit */
|
||||
tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
|
||||
/* write back result */
|
||||
tcg_gen_mov_tl(ret, result);
|
||||
|
||||
tcg_temp_free(temp);
|
||||
tcg_temp_free(result);
|
||||
}
|
||||
|
||||
static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
|
||||
{
|
||||
TCGv high = tcg_temp_new();
|
||||
TCGv low = tcg_temp_new();
|
||||
|
||||
tcg_gen_muls2_tl(low, high, r1, r2);
|
||||
tcg_gen_mov_tl(ret, low);
|
||||
/* calc V bit */
|
||||
tcg_gen_sari_tl(low, low, 31);
|
||||
tcg_gen_setcond_tl(TCG_COND_NE, cpu_PSW_V, high, low);
|
||||
tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
|
||||
/* calc SV bit */
|
||||
tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
|
||||
/* Calc AV bit */
|
||||
tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
|
||||
tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
|
||||
/* calc SAV bit */
|
||||
tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
|
||||
|
||||
tcg_temp_free(high);
|
||||
tcg_temp_free(low);
|
||||
}
|
||||
|
||||
static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
|
||||
{
|
||||
if (shift_count == -32) {
|
||||
@ -257,6 +304,16 @@ static void gen_shaci(TCGv ret, TCGv r1, int32_t shift_count)
|
||||
tcg_temp_free(t_0);
|
||||
}
|
||||
|
||||
static inline void gen_adds(TCGv ret, TCGv r1, TCGv r2)
|
||||
{
|
||||
gen_helper_add_ssov(ret, cpu_env, r1, r2);
|
||||
}
|
||||
|
||||
static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2)
|
||||
{
|
||||
gen_helper_sub_ssov(ret, cpu_env, r1, r2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions for decoding instructions
|
||||
*/
|
||||
@ -331,6 +388,89 @@ static void decode_src_opc(DisasContext *ctx, int op1)
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_srr_opc(DisasContext *ctx, int op1)
|
||||
{
|
||||
int r1, r2;
|
||||
TCGv temp;
|
||||
|
||||
r1 = MASK_OP_SRR_S1D(ctx->opcode);
|
||||
r2 = MASK_OP_SRR_S2(ctx->opcode);
|
||||
|
||||
switch (op1) {
|
||||
case OPC1_16_SRR_ADD:
|
||||
gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_ADD_A15:
|
||||
gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_ADD_15A:
|
||||
gen_add_d(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_ADD_A:
|
||||
tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], cpu_gpr_a[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_ADDS:
|
||||
gen_adds(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_AND:
|
||||
tcg_gen_and_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_CMOV:
|
||||
temp = tcg_const_tl(0);
|
||||
tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
|
||||
cpu_gpr_d[r2], cpu_gpr_d[r1]);
|
||||
tcg_temp_free(temp);
|
||||
break;
|
||||
case OPC1_16_SRR_CMOVN:
|
||||
temp = tcg_const_tl(0);
|
||||
tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
|
||||
cpu_gpr_d[r2], cpu_gpr_d[r1]);
|
||||
tcg_temp_free(temp);
|
||||
break;
|
||||
case OPC1_16_SRR_EQ:
|
||||
tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr_d[15], cpu_gpr_d[r1],
|
||||
cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_LT:
|
||||
tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr_d[15], cpu_gpr_d[r1],
|
||||
cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_MOV:
|
||||
tcg_gen_mov_tl(cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_MOV_A:
|
||||
tcg_gen_mov_tl(cpu_gpr_a[r1], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_MOV_AA:
|
||||
tcg_gen_mov_tl(cpu_gpr_a[r1], cpu_gpr_a[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_MOV_D:
|
||||
tcg_gen_mov_tl(cpu_gpr_d[r1], cpu_gpr_a[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_MUL:
|
||||
gen_mul_i32s(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_OR:
|
||||
tcg_gen_or_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_SUB:
|
||||
gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_SUB_A15B:
|
||||
gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_SUB_15AB:
|
||||
gen_sub_d(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_SUBS:
|
||||
gen_subs(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
break;
|
||||
case OPC1_16_SRR_XOR:
|
||||
tcg_gen_xor_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
|
||||
{
|
||||
int op1;
|
||||
@ -354,6 +494,30 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
|
||||
case OPC1_16_SRC_SHA:
|
||||
decode_src_opc(ctx, op1);
|
||||
break;
|
||||
/* SRR-format */
|
||||
case OPC1_16_SRR_ADD:
|
||||
case OPC1_16_SRR_ADD_A15:
|
||||
case OPC1_16_SRR_ADD_15A:
|
||||
case OPC1_16_SRR_ADD_A:
|
||||
case OPC1_16_SRR_ADDS:
|
||||
case OPC1_16_SRR_AND:
|
||||
case OPC1_16_SRR_CMOV:
|
||||
case OPC1_16_SRR_CMOVN:
|
||||
case OPC1_16_SRR_EQ:
|
||||
case OPC1_16_SRR_LT:
|
||||
case OPC1_16_SRR_MOV:
|
||||
case OPC1_16_SRR_MOV_A:
|
||||
case OPC1_16_SRR_MOV_AA:
|
||||
case OPC1_16_SRR_MOV_D:
|
||||
case OPC1_16_SRR_MUL:
|
||||
case OPC1_16_SRR_OR:
|
||||
case OPC1_16_SRR_SUB:
|
||||
case OPC1_16_SRR_SUB_A15B:
|
||||
case OPC1_16_SRR_SUB_15AB:
|
||||
case OPC1_16_SRR_SUBS:
|
||||
case OPC1_16_SRR_XOR:
|
||||
decode_srr_opc(ctx, op1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user