mirror of https://gitee.com/openkylin/qemu.git
TriCore v1.6.1 ISA and missing v1.6 instructions
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCgAGBQJVX0UVAAoJEArSxjlracoUHboP/1Ajq0KCGYuyTeOLcZbfSqgR frvtEl4Js2VqJ69p3XipZ8j16Co0U+gDm6Hu7/wytGXOSAplXwvlDe+556778MpV xVdsXoeh5X5xPMtoU3qEy6sK4bLxxmjAJtj4Ij1NojqRbRr1ZuvxxaUgB5ud1eWE Th/HQEhquAiZTfSilqu+xAMeFfRrpPlqIKFhHHOcctEZw03v0kTEfBMXw0AR5UW2 /ytvoBtiWnME2WYIkP6odWh96RthqigKhrCPbfnTFjD5amYeeeI0R8DeRKiDEWmY eEyddC5UcODIBfioj+aUbCf2jzu7LClu4MkyiFe0yK/SU2/Yz6v7GdgUhKsCoGAw noYbKOgilQtMBjs6hKbfxVIMmtkfz9dJ2y62H2PUzjCnFPhluZURE96T3p/e8HUo z3G+bTPZ69+7r4GxFMq8HpQE8hzC5xTZ8jA3bT+/8gYTyN8c0si4EF2XRBFhUm3H cjqSg8HTmoCQAPRkF29F1BrDyH/oPji2S5xLvtI4tG/Kk13ZhOcVxKky3wcK8Onf srCHdEsIThlMUCnAmphfqSCjliPXYmnZoGymeLfLRISPZrB4PmctTSbYdjdQU1kN ac5xa0NsL1wmFPLl2yk7TNFFpw0v1sH0SfpdxAjjVnj8B4jNRK6hleGFjpfjzpEE gl1/hij9FtqJPrx1Zgkz =NjJ8 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bkoppelmann/tags/pull-tricore-20150522' into staging TriCore v1.6.1 ISA and missing v1.6 instructions # gpg: Signature made Fri May 22 16:02:45 2015 BST using RSA key ID 6B69CA14 # gpg: Good signature from "Bastian Koppelmann <kbastian@mail.uni-paderborn.de>" * remotes/bkoppelmann/tags/pull-tricore-20150522: target-tricore: add RR_DIV and RR_DIV_U instructions of the v1.6 ISA target-tricore: add FRET instructions of the v1.6 ISA target-tricore: add FCALL instructions of the v1.6 ISA target-tricore: add SYS_RESTORE instruction of the v1.6 ISA target-tricore: add RR_CRC32 instruction of the v1.6.1 ISA target-tricore: add SWAPMSK instructions of the v1.6.1 ISA target-tricore: add CMPSWP instructions of the v1.6.1 ISA target-tricore: Add SRC_MOV_E instruction of the v1.6 ISA target-tricore: introduce ISA v1.6.1 feature target-tricore: Add ISA v1.3.1 cpu and fix tc1796 to using v1.3 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
bb2fa17f18
|
@ -68,6 +68,10 @@ static void tricore_cpu_realizefn(DeviceState *dev, Error **errp)
|
|||
CPUTriCoreState *env = &cpu->env;
|
||||
|
||||
/* Some features automatically imply others */
|
||||
if (tricore_feature(env, TRICORE_FEATURE_161)) {
|
||||
set_feature(env, TRICORE_FEATURE_16);
|
||||
}
|
||||
|
||||
if (tricore_feature(env, TRICORE_FEATURE_16)) {
|
||||
set_feature(env, TRICORE_FEATURE_131);
|
||||
}
|
||||
|
@ -118,14 +122,21 @@ static void tc1796_initfn(Object *obj)
|
|||
{
|
||||
TriCoreCPU *cpu = TRICORE_CPU(obj);
|
||||
|
||||
set_feature(&cpu->env, TRICORE_FEATURE_131);
|
||||
set_feature(&cpu->env, TRICORE_FEATURE_13);
|
||||
}
|
||||
|
||||
static void aurix_initfn(Object *obj)
|
||||
static void tc1797_initfn(Object *obj)
|
||||
{
|
||||
TriCoreCPU *cpu = TRICORE_CPU(obj);
|
||||
|
||||
set_feature(&cpu->env, TRICORE_FEATURE_16);
|
||||
set_feature(&cpu->env, TRICORE_FEATURE_131);
|
||||
}
|
||||
|
||||
static void tc27x_initfn(Object *obj)
|
||||
{
|
||||
TriCoreCPU *cpu = TRICORE_CPU(obj);
|
||||
|
||||
set_feature(&cpu->env, TRICORE_FEATURE_161);
|
||||
}
|
||||
|
||||
typedef struct TriCoreCPUInfo {
|
||||
|
@ -136,7 +147,8 @@ typedef struct TriCoreCPUInfo {
|
|||
|
||||
static const TriCoreCPUInfo tricore_cpus[] = {
|
||||
{ .name = "tc1796", .initfn = tc1796_initfn },
|
||||
{ .name = "aurix", .initfn = aurix_initfn },
|
||||
{ .name = "tc1797", .initfn = tc1797_initfn },
|
||||
{ .name = "tc27x", .initfn = tc27x_initfn },
|
||||
{ .name = NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -254,6 +254,7 @@ enum tricore_features {
|
|||
TRICORE_FEATURE_13,
|
||||
TRICORE_FEATURE_131,
|
||||
TRICORE_FEATURE_16,
|
||||
TRICORE_FEATURE_161,
|
||||
};
|
||||
|
||||
static inline int tricore_feature(CPUTriCoreState *env, int feature)
|
||||
|
|
|
@ -113,10 +113,14 @@ DEF_HELPER_3(dvinit_h_131, i64, env, i32, i32)
|
|||
DEF_HELPER_FLAGS_2(dvadj, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
DEF_HELPER_FLAGS_2(dvstep, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
DEF_HELPER_FLAGS_2(dvstep_u, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
DEF_HELPER_3(divide, i64, env, i32, i32)
|
||||
DEF_HELPER_3(divide_u, i64, env, i32, i32)
|
||||
/* mulh */
|
||||
DEF_HELPER_FLAGS_5(mul_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_5(mulm_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_5(mulr_h, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32, i32)
|
||||
/* crc32 */
|
||||
DEF_HELPER_FLAGS_2(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
/* CSA */
|
||||
DEF_HELPER_2(call, void, env, i32)
|
||||
DEF_HELPER_1(ret, void, env)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "qemu/host-utils.h"
|
||||
#include "exec/helper-proto.h"
|
||||
#include "exec/cpu_ldst.h"
|
||||
#include <zlib.h> /* for crc32 */
|
||||
|
||||
/* Addressing mode helper */
|
||||
|
||||
|
@ -2093,6 +2094,55 @@ uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
|
|||
return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
|
||||
}
|
||||
|
||||
uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
|
||||
{
|
||||
int32_t quotient, remainder;
|
||||
int32_t dividend = (int32_t)r1;
|
||||
int32_t divisor = (int32_t)r2;
|
||||
|
||||
if (divisor == 0) {
|
||||
if (dividend >= 0) {
|
||||
quotient = 0x7fffffff;
|
||||
remainder = 0;
|
||||
} else {
|
||||
quotient = 0x80000000;
|
||||
remainder = 0;
|
||||
}
|
||||
env->PSW_USB_V = (1 << 31);
|
||||
} else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) {
|
||||
quotient = 0x7fffffff;
|
||||
remainder = 0;
|
||||
env->PSW_USB_V = (1 << 31);
|
||||
} else {
|
||||
remainder = dividend % divisor;
|
||||
quotient = (dividend - remainder)/divisor;
|
||||
env->PSW_USB_V = 0;
|
||||
}
|
||||
env->PSW_USB_SV |= env->PSW_USB_V;
|
||||
env->PSW_USB_AV = 0;
|
||||
return ((uint64_t)remainder << 32) | (uint32_t)quotient;
|
||||
}
|
||||
|
||||
uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
|
||||
{
|
||||
uint32_t quotient, remainder;
|
||||
uint32_t dividend = r1;
|
||||
uint32_t divisor = r2;
|
||||
|
||||
if (divisor == 0) {
|
||||
quotient = 0xffffffff;
|
||||
remainder = 0;
|
||||
env->PSW_USB_V = (1 << 31);
|
||||
} else {
|
||||
remainder = dividend % divisor;
|
||||
quotient = (dividend - remainder)/divisor;
|
||||
env->PSW_USB_V = 0;
|
||||
}
|
||||
env->PSW_USB_SV |= env->PSW_USB_V;
|
||||
env->PSW_USB_AV = 0;
|
||||
return ((uint64_t)remainder << 32) | quotient;
|
||||
}
|
||||
|
||||
uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
|
||||
uint32_t arg10, uint32_t arg11, uint32_t n)
|
||||
{
|
||||
|
@ -2165,6 +2215,16 @@ uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
|
|||
return (result1 & 0xffff0000) | (result0 >> 16);
|
||||
}
|
||||
|
||||
uint32_t helper_crc32(uint32_t arg0, uint32_t arg1)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
uint32_t ret;
|
||||
stl_be_p(buf, arg0);
|
||||
|
||||
ret = crc32(arg1, buf, 4);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* context save area (CSA) related helpers */
|
||||
|
||||
static int cdc_increment(target_ulong *psw)
|
||||
|
|
|
@ -201,6 +201,15 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
|
|||
tcg_temp_free_i64(arg1); \
|
||||
} while (0)
|
||||
|
||||
#define GEN_HELPER_RR(name, rl, rh, arg1, arg2) do { \
|
||||
TCGv_i64 ret = tcg_temp_new_i64(); \
|
||||
\
|
||||
gen_helper_##name(ret, cpu_env, arg1, arg2); \
|
||||
tcg_gen_extr_i64_i32(rl, rh, ret); \
|
||||
\
|
||||
tcg_temp_free_i64(ret); \
|
||||
} while (0)
|
||||
|
||||
#define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
|
||||
#define EA_B_ABSOLUT(con) (((offset & 0xf00000) << 8) | \
|
||||
((offset & 0x0fffff) << 1))
|
||||
|
@ -319,6 +328,39 @@ static void gen_swap(DisasContext *ctx, int reg, TCGv ea)
|
|||
tcg_temp_free(temp);
|
||||
}
|
||||
|
||||
static void gen_cmpswap(DisasContext *ctx, int reg, TCGv ea)
|
||||
{
|
||||
TCGv temp = tcg_temp_new();
|
||||
TCGv temp2 = tcg_temp_new();
|
||||
tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
|
||||
tcg_gen_movcond_tl(TCG_COND_EQ, temp2, cpu_gpr_d[reg+1], temp,
|
||||
cpu_gpr_d[reg], temp);
|
||||
tcg_gen_qemu_st_tl(temp2, ea, ctx->mem_idx, MO_LEUL);
|
||||
tcg_gen_mov_tl(cpu_gpr_d[reg], temp);
|
||||
|
||||
tcg_temp_free(temp);
|
||||
tcg_temp_free(temp2);
|
||||
}
|
||||
|
||||
static void gen_swapmsk(DisasContext *ctx, int reg, TCGv ea)
|
||||
{
|
||||
TCGv temp = tcg_temp_new();
|
||||
TCGv temp2 = tcg_temp_new();
|
||||
TCGv temp3 = tcg_temp_new();
|
||||
|
||||
tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
|
||||
tcg_gen_and_tl(temp2, cpu_gpr_d[reg], cpu_gpr_d[reg+1]);
|
||||
tcg_gen_andc_tl(temp3, temp, cpu_gpr_d[reg+1]);
|
||||
tcg_gen_or_tl(temp2, temp2, temp3);
|
||||
tcg_gen_qemu_st_tl(temp2, ea, ctx->mem_idx, MO_LEUL);
|
||||
tcg_gen_mov_tl(cpu_gpr_d[reg], temp);
|
||||
|
||||
tcg_temp_free(temp);
|
||||
tcg_temp_free(temp2);
|
||||
tcg_temp_free(temp3);
|
||||
}
|
||||
|
||||
|
||||
/* We generate loads and store to core special function register (csfr) through
|
||||
the function gen_mfcr and gen_mtcr. To handle access permissions, we use 3
|
||||
makros R, A and E, which allow read-only, all and endinit protected access.
|
||||
|
@ -3242,6 +3284,32 @@ static void gen_loop(DisasContext *ctx, int r1, int32_t offset)
|
|||
gen_goto_tb(ctx, 0, ctx->next_pc);
|
||||
}
|
||||
|
||||
static void gen_fcall_save_ctx(DisasContext *ctx)
|
||||
{
|
||||
TCGv temp = tcg_temp_new();
|
||||
|
||||
tcg_gen_addi_tl(temp, cpu_gpr_a[10], -4);
|
||||
tcg_gen_qemu_st_tl(cpu_gpr_a[11], temp, ctx->mem_idx, MO_LESL);
|
||||
tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
|
||||
tcg_gen_mov_tl(cpu_gpr_a[10], temp);
|
||||
|
||||
tcg_temp_free(temp);
|
||||
}
|
||||
|
||||
static void gen_fret(DisasContext *ctx)
|
||||
{
|
||||
TCGv temp = tcg_temp_new();
|
||||
|
||||
tcg_gen_andi_tl(temp, cpu_gpr_a[11], ~0x1);
|
||||
tcg_gen_qemu_ld_tl(cpu_gpr_a[11], cpu_gpr_a[10], ctx->mem_idx, MO_LESL);
|
||||
tcg_gen_addi_tl(cpu_gpr_a[10], cpu_gpr_a[10], 4);
|
||||
tcg_gen_mov_tl(cpu_PC, temp);
|
||||
tcg_gen_exit_tb(0);
|
||||
ctx->bstate = BS_BRANCH;
|
||||
|
||||
tcg_temp_free(temp);
|
||||
}
|
||||
|
||||
static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
|
||||
int r2 , int32_t constant , int32_t offset)
|
||||
{
|
||||
|
@ -3336,6 +3404,14 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
|
|||
gen_helper_1arg(call, ctx->next_pc);
|
||||
gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
|
||||
break;
|
||||
case OPC1_32_B_FCALL:
|
||||
gen_fcall_save_ctx(ctx);
|
||||
gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
|
||||
break;
|
||||
case OPC1_32_B_FCALLA:
|
||||
gen_fcall_save_ctx(ctx);
|
||||
gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
|
||||
break;
|
||||
case OPC1_32_B_JLA:
|
||||
tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
|
||||
/* fall through */
|
||||
|
@ -3485,7 +3561,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
|
|||
* Functions for decoding instructions
|
||||
*/
|
||||
|
||||
static void decode_src_opc(DisasContext *ctx, int op1)
|
||||
static void decode_src_opc(CPUTriCoreState *env, DisasContext *ctx, int op1)
|
||||
{
|
||||
int r1;
|
||||
int32_t const4;
|
||||
|
@ -3546,6 +3622,12 @@ static void decode_src_opc(DisasContext *ctx, int op1)
|
|||
const4 = MASK_OP_SRC_CONST4(ctx->opcode);
|
||||
tcg_gen_movi_tl(cpu_gpr_a[r1], const4);
|
||||
break;
|
||||
case OPC1_16_SRC_MOV_E:
|
||||
if (tricore_feature(env, TRICORE_FEATURE_16)) {
|
||||
tcg_gen_movi_tl(cpu_gpr_d[r1], const4);
|
||||
tcg_gen_sari_tl(cpu_gpr_d[r1+1], cpu_gpr_d[r1], 31);
|
||||
} /* TODO: else raise illegal opcode trap */
|
||||
break;
|
||||
case OPC1_16_SRC_SH:
|
||||
gen_shi(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
|
||||
break;
|
||||
|
@ -3810,6 +3892,8 @@ static void decode_sr_system(CPUTriCoreState *env, DisasContext *ctx)
|
|||
case OPC2_16_SR_DEBUG:
|
||||
/* raise EXCP_DEBUG */
|
||||
break;
|
||||
case OPC2_16_SR_FRET:
|
||||
gen_fret(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3883,9 +3967,10 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
|
|||
case OPC1_16_SRC_LT:
|
||||
case OPC1_16_SRC_MOV:
|
||||
case OPC1_16_SRC_MOV_A:
|
||||
case OPC1_16_SRC_MOV_E:
|
||||
case OPC1_16_SRC_SH:
|
||||
case OPC1_16_SRC_SHA:
|
||||
decode_src_opc(ctx, op1);
|
||||
decode_src_opc(env, ctx, op1);
|
||||
break;
|
||||
/* SRR-format */
|
||||
case OPC1_16_SRR_ADD:
|
||||
|
@ -5039,6 +5124,30 @@ static void decode_bo_addrmode_stctx_post_pre_base(CPUTriCoreState *env,
|
|||
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
|
||||
gen_swap(ctx, r1, cpu_gpr_a[r2]);
|
||||
break;
|
||||
case OPC2_32_BO_CMPSWAP_W_SHORTOFF:
|
||||
tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
|
||||
gen_cmpswap(ctx, r1, temp);
|
||||
break;
|
||||
case OPC2_32_BO_CMPSWAP_W_POSTINC:
|
||||
gen_cmpswap(ctx, r1, cpu_gpr_a[r2]);
|
||||
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
|
||||
break;
|
||||
case OPC2_32_BO_CMPSWAP_W_PREINC:
|
||||
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
|
||||
gen_cmpswap(ctx, r1, cpu_gpr_a[r2]);
|
||||
break;
|
||||
case OPC2_32_BO_SWAPMSK_W_SHORTOFF:
|
||||
tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
|
||||
gen_swapmsk(ctx, r1, temp);
|
||||
break;
|
||||
case OPC2_32_BO_SWAPMSK_W_POSTINC:
|
||||
gen_swapmsk(ctx, r1, cpu_gpr_a[r2]);
|
||||
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
|
||||
break;
|
||||
case OPC2_32_BO_SWAPMSK_W_PREINC:
|
||||
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
|
||||
gen_swapmsk(ctx, r1, cpu_gpr_a[r2]);
|
||||
break;
|
||||
}
|
||||
tcg_temp_free(temp);
|
||||
tcg_temp_free(temp2);
|
||||
|
@ -5082,7 +5191,24 @@ static void decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env,
|
|||
gen_swap(ctx, r1, temp2);
|
||||
gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
|
||||
break;
|
||||
case OPC2_32_BO_CMPSWAP_W_BR:
|
||||
gen_cmpswap(ctx, r1, temp2);
|
||||
gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
|
||||
break;
|
||||
case OPC2_32_BO_CMPSWAP_W_CIRC:
|
||||
gen_cmpswap(ctx, r1, temp2);
|
||||
gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
|
||||
break;
|
||||
case OPC2_32_BO_SWAPMSK_W_BR:
|
||||
gen_swapmsk(ctx, r1, temp2);
|
||||
gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
|
||||
break;
|
||||
case OPC2_32_BO_SWAPMSK_W_CIRC:
|
||||
gen_swapmsk(ctx, r1, temp2);
|
||||
gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
|
||||
break;
|
||||
}
|
||||
|
||||
tcg_temp_free(temp);
|
||||
tcg_temp_free(temp2);
|
||||
tcg_temp_free(temp3);
|
||||
|
@ -6230,6 +6356,10 @@ static void decode_rr_idirect(CPUTriCoreState *env, DisasContext *ctx)
|
|||
gen_helper_1arg(call, ctx->next_pc);
|
||||
tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
|
||||
break;
|
||||
case OPC2_32_RR_FCALLI:
|
||||
gen_fcall_save_ctx(ctx);
|
||||
tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
|
||||
break;
|
||||
}
|
||||
tcg_gen_exit_tb(0);
|
||||
ctx->bstate = BS_BRANCH;
|
||||
|
@ -6368,6 +6498,23 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
|
|||
case OPC2_32_RR_UNPACK:
|
||||
gen_unpack(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
|
||||
break;
|
||||
case OPC2_32_RR_CRC32:
|
||||
if (tricore_feature(env, TRICORE_FEATURE_161)) {
|
||||
gen_helper_crc32(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
} /* TODO: else raise illegal opcode trap */
|
||||
break;
|
||||
case OPC2_32_RR_DIV:
|
||||
if (tricore_feature(env, TRICORE_FEATURE_16)) {
|
||||
GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
|
||||
cpu_gpr_d[r2]);
|
||||
} /* TODO: else raise illegal opcode trap */
|
||||
break;
|
||||
case OPC2_32_RR_DIV_U:
|
||||
if (tricore_feature(env, TRICORE_FEATURE_16)) {
|
||||
GEN_HELPER_RR(divide_u, cpu_gpr_d[r3], cpu_gpr_d[r3+1],
|
||||
cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||
} /* TODO: else raise illegal opcode trap */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7706,10 +7853,12 @@ static void decode_rrrw_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
|
|||
static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx)
|
||||
{
|
||||
uint32_t op2;
|
||||
uint32_t r1;
|
||||
TCGLabel *l1;
|
||||
TCGv tmp;
|
||||
|
||||
op2 = MASK_OP_SYS_OP2(ctx->opcode);
|
||||
r1 = MASK_OP_SYS_S1D(ctx->opcode);
|
||||
|
||||
switch (op2) {
|
||||
case OPC2_32_SYS_DEBUG:
|
||||
|
@ -7730,6 +7879,9 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx)
|
|||
case OPC2_32_SYS_RET:
|
||||
gen_compute_branch(ctx, op2, 0, 0, 0, 0);
|
||||
break;
|
||||
case OPC2_32_SYS_FRET:
|
||||
gen_fret(ctx);
|
||||
break;
|
||||
case OPC2_32_SYS_RFE:
|
||||
gen_helper_rfe(cpu_env);
|
||||
tcg_gen_exit_tb(0);
|
||||
|
@ -7758,6 +7910,14 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx)
|
|||
case OPC2_32_SYS_SVLCX:
|
||||
gen_helper_svlcx(cpu_env);
|
||||
break;
|
||||
case OPC2_32_SYS_RESTORE:
|
||||
if (tricore_feature(env, TRICORE_FEATURE_16)) {
|
||||
if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM ||
|
||||
(ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_UM1) {
|
||||
tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], 8, 1);
|
||||
} /* else raise privilege trap */
|
||||
} /* else raise illegal opcode trap */
|
||||
break;
|
||||
case OPC2_32_SYS_TRAPSV:
|
||||
/* TODO: raise sticky overflow trap */
|
||||
break;
|
||||
|
@ -7850,6 +8010,8 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
|
|||
/* B-format */
|
||||
case OPC1_32_B_CALL:
|
||||
case OPC1_32_B_CALLA:
|
||||
case OPC1_32_B_FCALL:
|
||||
case OPC1_32_B_FCALLA:
|
||||
case OPC1_32_B_J:
|
||||
case OPC1_32_B_JA:
|
||||
case OPC1_32_B_JL:
|
||||
|
|
|
@ -399,6 +399,7 @@ enum {
|
|||
OPC2_16_SR_RET = 0x09,
|
||||
OPC2_16_SR_RFE = 0x08,
|
||||
OPC2_16_SR_DEBUG = 0x0a,
|
||||
OPC2_16_SR_FRET = 0x07,
|
||||
};
|
||||
/* OPCM_16_SR_ACCU */
|
||||
enum {
|
||||
|
@ -428,6 +429,8 @@ enum {
|
|||
/* B Format */
|
||||
OPC1_32_B_CALL = 0x6d,
|
||||
OPC1_32_B_CALLA = 0xed,
|
||||
OPC1_32_B_FCALL = 0x61,
|
||||
OPC1_32_B_FCALLA = 0xe1,
|
||||
OPC1_32_B_J = 0x1d,
|
||||
OPC1_32_B_JA = 0x9d,
|
||||
OPC1_32_B_JL = 0x5d,
|
||||
|
@ -763,6 +766,12 @@ enum {
|
|||
OPC2_32_BO_SWAP_W_SHORTOFF = 0x20,
|
||||
OPC2_32_BO_SWAP_W_POSTINC = 0x00,
|
||||
OPC2_32_BO_SWAP_W_PREINC = 0x10,
|
||||
OPC2_32_BO_CMPSWAP_W_SHORTOFF = 0x23,
|
||||
OPC2_32_BO_CMPSWAP_W_POSTINC = 0x03,
|
||||
OPC2_32_BO_CMPSWAP_W_PREINC = 0x13,
|
||||
OPC2_32_BO_SWAPMSK_W_SHORTOFF = 0x22,
|
||||
OPC2_32_BO_SWAPMSK_W_POSTINC = 0x02,
|
||||
OPC2_32_BO_SWAPMSK_W_PREINC = 0x12,
|
||||
};
|
||||
/*OPCM_32_BO_ADDRMODE_LDMST_BITREVERSE_CIRCULAR */
|
||||
enum {
|
||||
|
@ -770,6 +779,10 @@ enum {
|
|||
OPC2_32_BO_LDMST_CIRC = 0x11,
|
||||
OPC2_32_BO_SWAP_W_BR = 0x00,
|
||||
OPC2_32_BO_SWAP_W_CIRC = 0x10,
|
||||
OPC2_32_BO_CMPSWAP_W_BR = 0x03,
|
||||
OPC2_32_BO_CMPSWAP_W_CIRC = 0x13,
|
||||
OPC2_32_BO_SWAPMSK_W_BR = 0x02,
|
||||
OPC2_32_BO_SWAPMSK_W_CIRC = 0x12,
|
||||
};
|
||||
/*
|
||||
* BRC Format
|
||||
|
@ -1110,12 +1123,16 @@ enum {
|
|||
OPC2_32_RR_DVINIT_U = 0x0a,
|
||||
OPC2_32_RR_PARITY = 0x02,
|
||||
OPC2_32_RR_UNPACK = 0x08,
|
||||
OPC2_32_RR_CRC32 = 0x03,
|
||||
OPC2_32_RR_DIV = 0x20,
|
||||
OPC2_32_RR_DIV_U = 0x21,
|
||||
};
|
||||
/* OPCM_32_RR_IDIRECT */
|
||||
enum {
|
||||
OPC2_32_RR_JI = 0x03,
|
||||
OPC2_32_RR_JLI = 0x02,
|
||||
OPC2_32_RR_CALLI = 0x00,
|
||||
OPC2_32_RR_FCALLI = 0x01,
|
||||
};
|
||||
/*
|
||||
* RR1 Format
|
||||
|
@ -1423,4 +1440,6 @@ enum {
|
|||
OPC2_32_SYS_SVLCX = 0x08,
|
||||
OPC2_32_SYS_TRAPSV = 0x15,
|
||||
OPC2_32_SYS_TRAPV = 0x14,
|
||||
OPC2_32_SYS_RESTORE = 0x0e,
|
||||
OPC2_32_SYS_FRET = 0x03,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue