e2k: Implement basic v5 support.
Add gdb xml files for e2k. Tags are partially disabled for better performance. Signed-off-by: Denis Drakhnya <numas13@gmail.com>
This commit is contained in:
parent
6fb98e718e
commit
8f4de9d485
|
@ -1 +1,2 @@
|
|||
TARGET_ARCH=e2k
|
||||
TARGET_XML_FILES= gdb-xml/e2k-v1.xml gdb-xml/e2k-v2.xml gdb-xml/e2k-v3.xml gdb-xml/e2k-v5.xml
|
|
@ -2,3 +2,4 @@ TARGET_ARCH=e2k32
|
|||
TARGET_BASE_ARCH=e2k
|
||||
TARGET_ABI_DIR=e2k
|
||||
TARGET_ABI32=y
|
||||
TARGET_XML_FILES= gdb-xml/e2k-v1.xml gdb-xml/e2k-v2.xml gdb-xml/e2k-v3.xml gdb-xml/e2k-v5.xml
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,6 @@
|
|||
<feature name="org.mcst.gdb.elbrus-v2.linux">
|
||||
|
||||
<!-- 840 -->
|
||||
<reg name="idr" bitsize="64" type="uint64"/>
|
||||
|
||||
</feature>
|
|
@ -0,0 +1,6 @@
|
|||
<feature name="org.mcst.gdb.elbrus-v3.linux">
|
||||
|
||||
<!-- 841 -->
|
||||
<reg name="core_mode" bitsize="64" type="uint64"/>
|
||||
|
||||
</feature>
|
|
@ -0,0 +1,86 @@
|
|||
<feature name="org.mcst.gdb.elbrus-v5.linux">
|
||||
|
||||
<!-- This type seems to be common for %lsr1 and %ilcr1 -->
|
||||
<!-- lsr1 -->
|
||||
<struct id="lsr1_bits" size="8">
|
||||
<field name="lcnt_lo" start="0" end="31"/>
|
||||
<field name="lcnt_hi" start="32" end="63"/>
|
||||
</struct>
|
||||
|
||||
<union id="lsr1">
|
||||
<field name="dword" type="uint64"/>
|
||||
<field name="" type="lsr1_bits"/>
|
||||
</union>
|
||||
|
||||
|
||||
<reg name="lsr1" bitsize="64" type="lsr1"/>
|
||||
<reg name="ilcr1" bitsize="64" type="lsr1"/>
|
||||
|
||||
<reg name="_gext_v5_0" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_1" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_2" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_3" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_4" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_5" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_6" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_7" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_8" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_9" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_10" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_11" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_12" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_13" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_14" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_15" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_16" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_17" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_18" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_19" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_20" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_21" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_22" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_23" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_24" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_25" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_26" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_27" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_28" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_29" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_30" bitsize="16" type="uint64"/>
|
||||
<reg name="_gext_v5_31" bitsize="16" type="uint64"/>
|
||||
|
||||
<reg name="_gtag_v5_0" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_1" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_2" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_3" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_4" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_5" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_6" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_7" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_8" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_9" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_10" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_11" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_12" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_13" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_14" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_15" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_16" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_17" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_18" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_19" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_20" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_21" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_22" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_23" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_24" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_25" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_26" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_27" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_28" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_29" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_30" bitsize="8" type="uint8"/>
|
||||
<reg name="_gtag_v5_31" bitsize="8" type="uint8"/>
|
||||
|
||||
|
||||
</feature>
|
|
@ -13,6 +13,8 @@
|
|||
#pragma GCC poison TARGET_ARM
|
||||
#pragma GCC poison TARGET_CRIS
|
||||
#pragma GCC poison TARGET_HEXAGON
|
||||
#pragma GCC poison TARGET_E2K
|
||||
#pragma GCC poison TARGET_E2K32
|
||||
#pragma GCC poison TARGET_HPPA
|
||||
#pragma GCC poison TARGET_LOONGARCH64
|
||||
#pragma GCC poison TARGET_M68K
|
||||
|
|
|
@ -400,6 +400,58 @@
|
|||
#define TARGET_NR_process_vm_writev 381
|
||||
#define TARGET_NR_kcmp 382
|
||||
#define TARGET_NR_finit_module 383
|
||||
#define TARGET_NR_syscalls 384
|
||||
#define TARGET_NR_renameat2 384
|
||||
#define TARGET_NR_getrandom 385
|
||||
#define TARGET_NR_memfd_create 386
|
||||
#define TARGET_NR_bpf 387
|
||||
#define TARGET_NR_execveat 388
|
||||
#define TARGET_NR_userfaultfd 389
|
||||
#define TARGET_NR_membarrier 390
|
||||
#define TARGET_NR_mlock2 391
|
||||
#define TARGET_NR_seccomp 392
|
||||
#define TARGET_NR_shutdown 393
|
||||
#define TARGET_NR_copy_file_range 394
|
||||
#define TARGET_NR_preadv2 395
|
||||
#define TARGET_NR_pwritev2 396
|
||||
#define TARGET_NR_pkey_mprotect 397
|
||||
#define TARGET_NR_pkey_alloc 398
|
||||
#define TARGET_NR_pkey_free 399
|
||||
#define TARGET_NR_name_to_handle_at 400
|
||||
#define TARGET_NR_open_by_handle_at 401
|
||||
#define TARGET_NR_statx 402
|
||||
/* added for compatibility with x86_64 */
|
||||
#define TARGET_NR_socket 403
|
||||
#define TARGET_NR_connect 404
|
||||
#define TARGET_NR_accept 405
|
||||
#define TARGET_NR_sendto 406
|
||||
#define TARGET_NR_recvfrom 407
|
||||
#define TARGET_NR_sendmsg 408
|
||||
#define TARGET_NR_recvmsg 409
|
||||
#define TARGET_NR_bind 410
|
||||
#define TARGET_NR_listen 411
|
||||
#define TARGET_NR_getsockname 412
|
||||
#define TARGET_NR_getpeername 413
|
||||
#define TARGET_NR_socketpair 414
|
||||
#define TARGET_NR_setsockopt 415
|
||||
#define TARGET_NR_getsockopt 416
|
||||
/* free (unused) entries - reserve 417 - 418 */
|
||||
/* TODO: #define TARGET_NR_arch_prctl 419 */
|
||||
/* added for combability of protected system calls v1-v5 & v6 */
|
||||
#define TARGET_NR_newuselib 420
|
||||
#define TARGET_NR_rt_sigaction_ex 421
|
||||
/* protected Mode specific memory allocation syscall number */
|
||||
#define TARGET_NR_get_mem 422
|
||||
#define TARGET_NR_free_mem 423
|
||||
/* protected mode specific clean memory from old invalid descriptors */
|
||||
#define TARGET_NR_clean_descriptors 424
|
||||
/* protected mode specific unloading module from memory */
|
||||
#define TARGET_NR_unuselib 425
|
||||
#define TARGET_NR_clone3 426
|
||||
#define TARGET_NR_fsopen 427
|
||||
#define TARGET_NR_fsconfig 428
|
||||
#define TARGET_NR_fsmount 429
|
||||
#define TARGET_NR_fspick 430
|
||||
|
||||
#define TARGET_syscalls 431
|
||||
|
||||
#endif /* E2K_SYSCALL_NR_H */
|
||||
|
|
1726
target/e2k/alops.inc
1726
target/e2k/alops.inc
File diff suppressed because it is too large
Load Diff
|
@ -238,6 +238,8 @@ static void e2k_cpu_realizefn(DeviceState *dev, Error **errp)
|
|||
return;
|
||||
}
|
||||
|
||||
e2k_cpu_register_gdb_regs_for_features(cs);
|
||||
|
||||
qemu_init_vcpu(cs);
|
||||
|
||||
ecc->parent_realize(dev, errp);
|
||||
|
@ -291,6 +293,7 @@ static void e2k_cpu_class_init(ObjectClass *oc, void *data)
|
|||
cc->class_by_name = e2k_cpu_class_by_name;
|
||||
cc->disas_set_info = cpu_e2k_disas_set_info;
|
||||
|
||||
cc->gdb_core_xml_file = "e2k-v1.xml";
|
||||
cc->gdb_arch_name = e2k_cpu_gdb_arch_name;
|
||||
cc->gdb_read_register = e2k_cpu_gdb_read_register;
|
||||
cc->gdb_write_register = e2k_cpu_gdb_write_register;
|
||||
|
|
|
@ -28,6 +28,8 @@ void e2k_tcg_initialize(void);
|
|||
*/
|
||||
#define E2K_FORCE_FX true
|
||||
|
||||
//#define E2K_TAGS_ENABLE
|
||||
|
||||
#define GEN_MASK(start, len) (((1UL << (len)) - 1) << (start))
|
||||
#define GET_BIT(v, index) (((v) >> (index)) & 1)
|
||||
|
||||
|
@ -55,12 +57,17 @@ void e2k_tcg_initialize(void);
|
|||
typedef enum {
|
||||
E2K_TAG_NUMBER32 = 0,
|
||||
E2K_TAG_NUMBER64 = 0,
|
||||
E2K_TAG_NON_NUMBER32 = 1,
|
||||
E2K_TAG_NON_NUMBER64 = 5,
|
||||
E2K_TAG_NUMBER80 = 0,
|
||||
E2K_TAG_NUMBER128 = 0,
|
||||
|
||||
E2K_TAG_NON_NUMBER32 = 0x01,
|
||||
E2K_TAG_NON_NUMBER64 = 0x05,
|
||||
E2K_TAG_NON_NUMBER80 = 0x05,
|
||||
E2K_TAG_NON_NUMBER128 = 0x55,
|
||||
} E2kRegisterTag;
|
||||
|
||||
#define E2K_MOVA_RESULT_INVALID 0xeaed0f70eaed0f70
|
||||
#define E2K_LD_RESULT_INVALID 0x0afafafa0afafafa
|
||||
#define E2K_LD_RESULT_INVALID 0x4afafafa4afafafa
|
||||
|
||||
#define CRS_SIZE (sizeof(E2KCrs))
|
||||
|
||||
|
@ -689,14 +696,17 @@ typedef union {
|
|||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
floatx80 f80;
|
||||
uint8_t u8v[16];
|
||||
uint16_t u16v[8];
|
||||
uint32_t u32v[4];
|
||||
uint64_t u64v[2];
|
||||
int8_t i8v[16];
|
||||
int16_t i16v[8];
|
||||
int32_t i32v[4];
|
||||
int64_t i64v[2];
|
||||
|
||||
uint8_t ub[16];
|
||||
uint16_t uh[8];
|
||||
uint32_t uw[4];
|
||||
uint64_t ud[2];
|
||||
|
||||
int8_t sb[16];
|
||||
int16_t sh[8];
|
||||
int32_t sw[4];
|
||||
int64_t sd[2];
|
||||
|
||||
struct {
|
||||
uint64_t lo;
|
||||
uint64_t hi;
|
||||
|
@ -714,7 +724,7 @@ typedef struct CPUArchState {
|
|||
E2KReg t0, t1, t2, t3;
|
||||
|
||||
E2KReg tmp[8];
|
||||
E2KReg al_result[6];
|
||||
E2KReg al_result[16];
|
||||
|
||||
/* DAM */
|
||||
E2KDamEntry dam[32];
|
||||
|
@ -731,7 +741,7 @@ typedef struct CPUArchState {
|
|||
|
||||
/* loop status register */
|
||||
uint64_t lsr;
|
||||
uint32_t lsr_lcnt;
|
||||
uint64_t lsr_lcnt;
|
||||
uint32_t lsr_ecnt;
|
||||
uint32_t lsr_vlc;
|
||||
uint32_t lsr_over;
|
||||
|
@ -763,7 +773,8 @@ typedef struct CPUArchState {
|
|||
|
||||
/* internal use */
|
||||
uint32_t is_bp; /* breakpoint flag */
|
||||
uint64_t last_value; /* ld mas=7 + st mas=2 */
|
||||
uint64_t last_val0; /* ld mas=7 + st mas=2 */
|
||||
uint64_t last_val1; /* ld mas=7 + st mas=2 */
|
||||
|
||||
/* zeroing upper register half for 32-bit instructions */
|
||||
uint32_t wdbl;
|
||||
|
@ -815,6 +826,7 @@ void e2k_cpu_list(void);
|
|||
int e2k_cpu_signal_handler(int host_signum, void *pinfo, void *puc);
|
||||
int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n);
|
||||
int e2k_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n);
|
||||
void e2k_cpu_register_gdb_regs_for_features(CPUState *cs);
|
||||
bool e2k_cpu_tlb_fill(CPUState *cpu, vaddr address, int size,
|
||||
MMUAccessType access_type, int mmu_idx,
|
||||
bool probe, uintptr_t retaddr);
|
||||
|
@ -882,7 +894,7 @@ static inline uint32_t e2k_state_br(CPUE2KState *env)
|
|||
ret = deposit32(ret, BR_RSZ_OFF, BR_RSZ_LEN, bn->size / 2 - 1);
|
||||
ret = deposit32(ret, BR_RCUR_OFF, BR_RCUR_LEN, bn->cur / 2);
|
||||
|
||||
ret = deposit32(ret, BR_PSZ_OFF, BR_PSZ_LEN, bp->size);
|
||||
ret = deposit32(ret, BR_PSZ_OFF, BR_PSZ_LEN, bp->size - 1);
|
||||
ret = deposit32(ret, BR_PCUR_OFF, BR_PCUR_LEN, bp->cur);
|
||||
|
||||
return ret;
|
||||
|
@ -897,7 +909,7 @@ static inline void e2k_state_br_set(CPUE2KState *env, uint32_t br)
|
|||
bn->size = extract32(br, BR_RSZ_OFF, BR_RSZ_LEN) * 2 + 2;
|
||||
bn->cur = extract32(br, BR_RCUR_OFF, BR_RCUR_LEN) * 2;
|
||||
|
||||
bp->size = extract32(br, BR_PSZ_OFF, BR_PSZ_LEN);
|
||||
bp->size = extract32(br, BR_PSZ_OFF, BR_PSZ_LEN) + 1;
|
||||
bp->cur = extract32(br, BR_PCUR_OFF, BR_PCUR_LEN);
|
||||
}
|
||||
|
||||
|
|
|
@ -295,3 +295,78 @@ int e2k_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
|||
// TODO: e2k_cpu_gdb_write_register
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gdb_get_v2(CPUE2KState *env, GByteArray *buf, int n)
|
||||
{
|
||||
if (n == 0) {
|
||||
/* idr */
|
||||
return gdb_get_reg64(buf, env->idr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gdb_set_v2(CPUE2KState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
fprintf(stderr, "%s: unknown register %d\n", __FUNCTION__, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gdb_get_v3(CPUE2KState *env, GByteArray *buf, int n)
|
||||
{
|
||||
if (n == 0) {
|
||||
/* TODO: core_mode */
|
||||
return gdb_get_reg64(buf, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gdb_set_v3(CPUE2KState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
fprintf(stderr, "%s: unknown register %d\n", __FUNCTION__, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gdb_get_v5(CPUE2KState *env, GByteArray *buf, int n)
|
||||
{
|
||||
if (n == 0) {
|
||||
return gdb_get_reg64(buf, env->lsr_lcnt);
|
||||
} else if (n == 1) {
|
||||
// TODO: ilcr1
|
||||
return gdb_get_reg64(buf, 0);
|
||||
} else if (n >= 2 && n < 34) {
|
||||
return gdb_get_reg64(buf, env->regs[E2K_NR_COUNT + n - 2].hi);
|
||||
} else if (n >= 34 && n < 66) {
|
||||
return gdb_get_reg8(buf, env->tags[E2K_NR_COUNT + n - 34]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gdb_set_v5(CPUE2KState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
fprintf(stderr, "%s: unknown register %d\n", __FUNCTION__, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void e2k_cpu_register_gdb_regs_for_features(CPUState *cs)
|
||||
{
|
||||
E2KCPU *cpu = E2K_CPU(cs);
|
||||
CPUE2KState *env = &cpu->env;
|
||||
|
||||
if (env->version >= 2) {
|
||||
gdb_register_coprocessor(cs, gdb_get_v2, gdb_set_v2,
|
||||
1, "e2k-v2.xml", 574);
|
||||
}
|
||||
|
||||
if (env->version >= 3) {
|
||||
gdb_register_coprocessor(cs, gdb_get_v3, gdb_set_v3,
|
||||
1, "e2k-v3.xml", 575);
|
||||
}
|
||||
|
||||
if (env->version >= 5) {
|
||||
gdb_register_coprocessor(cs, gdb_get_v5, gdb_set_v5,
|
||||
66, "e2k-v5.xml", 576);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,9 @@ static inline void ps_push(CPUE2KState *env, uint64_t value, uint8_t tag)
|
|||
#endif
|
||||
|
||||
cpu_stq_le_data(env, env->psp.base + env->psp.index, value);
|
||||
#ifdef E2K_TAGS_ENABLE
|
||||
cpu_stb_data(env, env->psp.base_tag + env->psp.index / 8, tag);
|
||||
#endif
|
||||
env->psp.index += 8;
|
||||
}
|
||||
|
||||
|
@ -34,20 +36,37 @@ static inline uint64_t ps_pop(CPUE2KState *env, uint8_t *ret_tag)
|
|||
}
|
||||
env->psp.index -= 8;
|
||||
if (ret_tag != NULL) {
|
||||
#ifdef E2K_TAGS_ENABLE
|
||||
*ret_tag = cpu_ldub_data(env, env->psp.base_tag + env->psp.index / 8);
|
||||
#else
|
||||
*ret_tag = 0;
|
||||
#endif
|
||||
}
|
||||
return cpu_ldq_le_data(env, env->psp.base + env->psp.index);
|
||||
}
|
||||
|
||||
|
||||
static void ps_spill(CPUE2KState *env, int n, bool fx)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i += 2) {
|
||||
ps_push(env, env->regs[i + 0].lo, env->tags[i]);
|
||||
ps_push(env, env->regs[i + 1].lo, env->tags[i + 1]);
|
||||
|
||||
if (env->version >= 5) {
|
||||
for (i = 0; i < n; i++) {
|
||||
ps_push(env, env->regs[i].lo, env->tags[i]);
|
||||
if (fx || E2K_FORCE_FX) {
|
||||
ps_push(env, env->regs[i + 0].hi, 0);
|
||||
ps_push(env, env->regs[i + 1].hi, 0);
|
||||
ps_push(env, env->regs[i].hi, 0);
|
||||
}
|
||||
}
|
||||
} else{
|
||||
for (i = 0; i < n; i += 2) {
|
||||
E2KReg r0 = env->regs[i + 0];
|
||||
E2KReg r1 = env->regs[i + 1];
|
||||
ps_push(env, r0.lo, env->tags[i]);
|
||||
ps_push(env, r1.lo, env->tags[i + 1]);
|
||||
if (fx || E2K_FORCE_FX) {
|
||||
ps_push(env, r0.hi, 0);
|
||||
ps_push(env, r1.hi, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,20 +74,34 @@ static void ps_spill(CPUE2KState *env, int n, bool fx)
|
|||
static void ps_fill(CPUE2KState *env, int n, bool fx)
|
||||
{
|
||||
int i;
|
||||
for (i = n; i > 0; i -= 2) {
|
||||
|
||||
if (env->version >= 5) {
|
||||
for (i = n; i-- > 0;) {
|
||||
if (fx || E2K_FORCE_FX) {
|
||||
env->regs[i - 1].hi = ps_pop(env, NULL);
|
||||
env->regs[i - 2].hi = ps_pop(env, NULL);
|
||||
env->regs[i].hi = ps_pop(env, NULL);
|
||||
}
|
||||
env->regs[i].lo = ps_pop(env, &env->tags[i]);
|
||||
}
|
||||
} else {
|
||||
for (i = n; i > 0; i -= 2) {
|
||||
E2KReg *r0 = &env->regs[i - 1];
|
||||
E2KReg *r1 = &env->regs[i - 2];
|
||||
if (fx || E2K_FORCE_FX) {
|
||||
r0->hi = ps_pop(env, NULL);
|
||||
r1->hi = ps_pop(env, NULL);
|
||||
}
|
||||
r0->lo = ps_pop(env, &env->tags[i - 1]);
|
||||
r1->lo = ps_pop(env, &env->tags[i - 2]);
|
||||
}
|
||||
env->regs[i - 1].lo = ps_pop(env, &env->tags[i - 1]);
|
||||
env->regs[i - 2].lo = ps_pop(env, &env->tags[i - 2]);
|
||||
}
|
||||
}
|
||||
|
||||
static void move_regs(CPUE2KState *env, int dst, int src, int n)
|
||||
{
|
||||
memmove(&env->regs[dst], &env->regs[src], n * sizeof(env->regs[0]));
|
||||
#ifdef E2K_TAGS_ENABLE
|
||||
memmove(&env->tags[dst], &env->tags[src], n * sizeof(env->tags[0]));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void callee_window(CPUE2KState *env, int base, int size, bool fx)
|
||||
|
@ -293,10 +326,12 @@ void HELPER(setwd)(CPUE2KState *env, int wsz, int nfx, int dbl)
|
|||
|
||||
if (diff > 0) {
|
||||
// FIXME: zeroing registers is not needed, but useful for debugging
|
||||
#if 1
|
||||
#if 0
|
||||
memset(&env->regs[env->wd.size], 0, diff * sizeof(env->regs[0]));
|
||||
#endif
|
||||
#ifdef E2K_TAGS_ENABLE
|
||||
memset(&env->tags[env->wd.size], E2K_TAG_NON_NUMBER64, diff);
|
||||
#endif
|
||||
}
|
||||
|
||||
env->wd.size = size;
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
// TODO: set helper call flags
|
||||
|
||||
#define dh_alias_Reg ptr
|
||||
#define dh_alias_vec ptr
|
||||
#define dh_alias_f80 ptr
|
||||
#define dh_ctype_Reg E2KReg *
|
||||
#define dh_ctype_vec E2KReg *
|
||||
#define dh_ctype_f80 floatx80 *
|
||||
#define dh_typecode_Reg dh_typecode_ptr
|
||||
#define dh_typecode_vec dh_typecode_ptr
|
||||
#define dh_typecode_f80 dh_typecode_ptr
|
||||
#define dh_is_signed_Reg dh_is_signed_ptr
|
||||
#define dh_is_signed_vec dh_is_signed_ptr
|
||||
#define dh_is_signed_f80 dh_is_signed_ptr
|
||||
|
||||
DEF_HELPER_2(raise_exception, noreturn, env, int)
|
||||
|
@ -67,11 +65,19 @@ DEF_HELPER_FLAGS_2(phaddh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
|||
DEF_HELPER_FLAGS_2(phaddw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(phaddsh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
|
||||
DEF_HELPER_FLAGS_3(qphaddh, TCG_CALL_NO_RWG, void, vec, vec, vec)
|
||||
DEF_HELPER_FLAGS_3(qphaddw, TCG_CALL_NO_RWG, void, vec, vec, vec)
|
||||
DEF_HELPER_FLAGS_3(qphaddsh, TCG_CALL_NO_RWG, void, vec, vec, vec)
|
||||
|
||||
/* Packed Horizontal Sub */
|
||||
DEF_HELPER_FLAGS_2(phsubh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(phsubw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(phsubsh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
|
||||
DEF_HELPER_FLAGS_3(qphsubh, TCG_CALL_NO_RWG, void, vec, vec, vec)
|
||||
DEF_HELPER_FLAGS_3(qphsubw, TCG_CALL_NO_RWG, void, vec, vec, vec)
|
||||
DEF_HELPER_FLAGS_3(qphsubsh, TCG_CALL_NO_RWG, void, vec, vec, vec)
|
||||
|
||||
/* Packed Add using saturation */
|
||||
DEF_HELPER_FLAGS_2(paddsb, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(paddsh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
|
@ -87,8 +93,10 @@ DEF_HELPER_FLAGS_2(psubush, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
|||
/* Packed shifts */
|
||||
DEF_HELPER_FLAGS_2(psllh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(psllw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(pslld, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(psrlh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(psrlw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(psrld, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
|
||||
/* Packed shifts with sign */
|
||||
DEF_HELPER_FLAGS_2(psrah, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
|
@ -141,6 +149,14 @@ DEF_HELPER_FLAGS_2(phminposuh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
|||
DEF_HELPER_FLAGS_2(mpsadbh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_4(plog, TCG_CALL_NO_RWG_SE, i64, i32, i64, i64, i64)
|
||||
|
||||
DEF_HELPER_FLAGS_3(qpmpsadbh, TCG_CALL_NO_RWG, void, vec, vec, i32)
|
||||
DEF_HELPER_FLAGS_3(qpmulubhh, TCG_CALL_NO_RWG, void, vec, i64, vec)
|
||||
DEF_HELPER_FLAGS_2(qphminposuh, TCG_CALL_NO_RWG_SE, i64, vec, vec)
|
||||
DEF_HELPER_FLAGS_1(qpsgn2mskb, TCG_CALL_NO_RWG_SE, i32, vec)
|
||||
DEF_HELPER_FLAGS_3(qpmsk2sgnb, TCG_CALL_NO_RWG, void, vec, vec, i32)
|
||||
DEF_HELPER_FLAGS_4(qppermb, TCG_CALL_NO_RWG, void, vec, vec, vec, vec)
|
||||
DEF_HELPER_FLAGS_4(qpshufb, TCG_CALL_NO_RWG, void, vec, vec, vec, vec)
|
||||
|
||||
/* Float 32/64 Ops */
|
||||
DEF_HELPER_FLAGS_3(fadds, TCG_CALL_NO_RWG, i32, env, i32, i32)
|
||||
DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_RWG, i32, env, i32, i32)
|
||||
|
@ -172,12 +188,24 @@ DEF_HELPER_FLAGS_3(pfmins, TCG_CALL_NO_RWG, i64, env, i64, i64)
|
|||
DEF_HELPER_FLAGS_3(pfhadds, TCG_CALL_NO_RWG, i64, env, i64, i64)
|
||||
DEF_HELPER_FLAGS_3(pfhsubs, TCG_CALL_NO_RWG, i64, env, i64, i64)
|
||||
DEF_HELPER_FLAGS_3(pfaddsubs, TCG_CALL_NO_RWG, i64, env, i64, i64)
|
||||
DEF_HELPER_FLAGS_4(qpfhadds, TCG_CALL_NO_RWG, void, vec, env, vec, vec)
|
||||
DEF_HELPER_FLAGS_4(qpfhsubs, TCG_CALL_NO_RWG, void, vec, env, vec, vec)
|
||||
|
||||
DEF_HELPER_FLAGS_3(pfstoifs, TCG_CALL_NO_RWG, i64, env, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(pistofs, TCG_CALL_NO_RWG, i64, env, i64)
|
||||
DEF_HELPER_FLAGS_2(pfstois, TCG_CALL_NO_RWG, i64, env, i64)
|
||||
DEF_HELPER_FLAGS_2(pfstoistr, TCG_CALL_NO_RWG, i64, env, i64)
|
||||
|
||||
DEF_HELPER_FLAGS_3(qpfstoid, TCG_CALL_NO_RWG, void, vec, env, i64)
|
||||
DEF_HELPER_FLAGS_3(qpfstoidtr, TCG_CALL_NO_RWG, void, vec, env, i64)
|
||||
DEF_HELPER_FLAGS_3(qpistofd, TCG_CALL_NO_RWG, void, vec, env, i64)
|
||||
DEF_HELPER_FLAGS_3(qpfstofd, TCG_CALL_NO_RWG, void, vec, env, i64)
|
||||
|
||||
DEF_HELPER_FLAGS_2(qpfdtois, TCG_CALL_NO_RWG, i64, env, vec)
|
||||
DEF_HELPER_FLAGS_2(qpfdtoistr, TCG_CALL_NO_RWG, i64, env, vec)
|
||||
DEF_HELPER_FLAGS_2(qpidtofs, TCG_CALL_NO_RWG, i64, env, vec)
|
||||
DEF_HELPER_FLAGS_2(qpfdtofs, TCG_CALL_NO_RWG, i64, env, vec)
|
||||
|
||||
DEF_HELPER_FLAGS_3(pfcmpeqs, TCG_CALL_NO_RWG, i64, env, i64, i64)
|
||||
DEF_HELPER_FLAGS_3(pfcmplts, TCG_CALL_NO_RWG, i64, env, i64, i64)
|
||||
DEF_HELPER_FLAGS_3(pfcmples, TCG_CALL_NO_RWG, i64, env, i64, i64)
|
||||
|
|
|
@ -68,6 +68,7 @@ uint64_t HELPER(rrd)(CPUE2KState *env, int idx)
|
|||
case 0x86: return env->fpsr.raw; /* %fpsr */
|
||||
case 0x8a: return env->idr; /* %idr */
|
||||
case 0x90: return cpu_get_host_ticks(); /* %clkr */
|
||||
case 0xc3: return env->lsr_lcnt; /* %lsr1 */
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "read unknown state register 0x%x\n", idx);
|
||||
return 0;
|
||||
|
@ -98,6 +99,7 @@ void HELPER(rwd)(CPUE2KState *env, int idx, uint64_t val)
|
|||
e2k_update_fx_status(env);
|
||||
break;
|
||||
case 0x86: env->fpsr.raw = val; break; /* %fpsr */
|
||||
case 0xc3: env->lsr_lcnt = val; break; /* %lsr1 */
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "rwd unknown state register 0x%x\n", idx);
|
||||
break;
|
||||
|
|
|
@ -26,6 +26,18 @@ static uint8_t reverse_bits(uint8_t b)
|
|||
|
||||
#define vec64_len(type) glue(vec64_, type)
|
||||
|
||||
#define vec128_ub 16
|
||||
#define vec128_uh 8
|
||||
#define vec128_uw 4
|
||||
#define vec128_ud 2
|
||||
|
||||
#define vec128_sb vec128_ub
|
||||
#define vec128_sh vec128_uh
|
||||
#define vec128_sw vec128_uw
|
||||
#define vec128_sd vec128_ud
|
||||
|
||||
#define vec128_len(type) glue(vec128_, type)
|
||||
|
||||
typedef union {
|
||||
uint8_t ub[vec64_ub];
|
||||
uint16_t uh[vec64_uh];
|
||||
|
@ -63,10 +75,12 @@ typedef union {
|
|||
}
|
||||
#define GEN_HELPER_PACKED(name, type, code) \
|
||||
GEN_HELPER_PACKED_N(name, vec64_len(type), code)
|
||||
|
||||
#define GEN_HELPER_PACKED_OP(name, type, op) \
|
||||
GEN_HELPER_PACKED_N(name, vec64_len(type), { \
|
||||
dst.type[i] = op(s1.type[i], s2.type[i]); \
|
||||
})
|
||||
|
||||
#define GEN_HELPER_PACKED_SCALAR(name, type, code) \
|
||||
uint64_t HELPER(name)(uint64_t src1, uint64_t s2) \
|
||||
{ \
|
||||
|
@ -77,11 +91,28 @@ typedef union {
|
|||
} \
|
||||
return dst.ud[0]; \
|
||||
}
|
||||
#define GEN_HELPER_PACKED_MINMAX(name, type, op) \
|
||||
GEN_HELPER_PACKED(glue(name, type), type, { \
|
||||
dst.type[i] = op(s1.type[i], s2.type[i]); \
|
||||
|
||||
#define IMPL_QPACKED_N(name, n, code) \
|
||||
void HELPER(name)(E2KReg *r, E2KReg *s1, E2KReg *s2) \
|
||||
{ \
|
||||
int i; \
|
||||
\
|
||||
for (i = 0; i < n; i++) { \
|
||||
code \
|
||||
} \
|
||||
}
|
||||
|
||||
#define IMPL_QPACKED(name, type, code) \
|
||||
IMPL_QPACKED_N(name, vec64_len(type), code)
|
||||
|
||||
#define IMPL_QPACKED_OP(name, type, op) \
|
||||
IMPL_QPACKED_N(name, vec128_len(type), { \
|
||||
r->type[i] = op(s1->type[i], s2->type[i]); \
|
||||
})
|
||||
|
||||
#define GEN_HELPER_PACKED_MINMAX(name, type, op) \
|
||||
GEN_HELPER_PACKED_OP(glue(name, type), type, op)
|
||||
|
||||
GEN_HELPER_PACKED_MINMAX(pmin, ub, MIN)
|
||||
GEN_HELPER_PACKED_MINMAX(pmin, sb, MIN)
|
||||
GEN_HELPER_PACKED_MINMAX(pmin, uh, MIN)
|
||||
|
@ -131,6 +162,11 @@ GEN_HELPER_PACKED_BINOP_MAP(psubush, uh, -, int32_t, satuh)
|
|||
int j = i * 2; \
|
||||
dst.type[i ] = map(op(s1.type[j], s1.type[j + 1])); \
|
||||
dst.type[i + vec64_len(type) / 2] = map(op(s2.type[j], s2.type[j + 1])); \
|
||||
}) \
|
||||
IMPL_QPACKED_N(glue(q, name), vec128_len(type) / 2, { \
|
||||
int j = i * 2; \
|
||||
r->type[i ] = map(op(s1->type[j], s1->type[j + 1])); \
|
||||
r->type[i + vec128_len(type) / 2] = map(op(s2->type[j], s2->type[j + 1])); \
|
||||
})
|
||||
|
||||
GEN_HELPER_PACKED_HORIZONTAL_OP(phaddh, sh, add, ident)
|
||||
|
@ -142,14 +178,15 @@ GEN_HELPER_PACKED_HORIZONTAL_OP(phsubsh, sh, sub, satsh)
|
|||
|
||||
#define GEN_HELPER_PACKED_SCALAR_BINOP(name, type, op) \
|
||||
GEN_HELPER_PACKED_SCALAR(name, type, { \
|
||||
int max = sizeof(s1.type[0]) * 8 - 1; \
|
||||
dst.type[i] = s2 < s1.type[i] op ( s2 < max ? s2 : max); \
|
||||
dst.type[i] = s2 < sizeof(s1.type[0]) * 8 ? s1.type[i] op s2 : 0; \
|
||||
})
|
||||
|
||||
GEN_HELPER_PACKED_SCALAR_BINOP(psllh, uh, <<)
|
||||
GEN_HELPER_PACKED_SCALAR_BINOP(psllw, uw, <<)
|
||||
GEN_HELPER_PACKED_SCALAR_BINOP(pslld, ud, <<)
|
||||
GEN_HELPER_PACKED_SCALAR_BINOP(psrlh, uh, >>)
|
||||
GEN_HELPER_PACKED_SCALAR_BINOP(psrlw, uw, >>)
|
||||
GEN_HELPER_PACKED_SCALAR_BINOP(psrld, ud, >>)
|
||||
|
||||
#define GEN_HELPER_PACKED_SRA(name, type, t) \
|
||||
GEN_HELPER_PACKED_SCALAR(name, type, { \
|
||||
|
@ -239,7 +276,7 @@ GEN_HELPER_PACKED_UNPACK(punpckhwd, uw, 1)
|
|||
uint64_t HELPER(pshufb)(uint64_t src1, uint64_t src2, uint64_t src3)
|
||||
{
|
||||
vec64 ret, s1, s2, s3;
|
||||
unsigned int i;
|
||||
int i;
|
||||
|
||||
s1.ud[0] = src1;
|
||||
s2.ud[0] = src2;
|
||||
|
@ -272,7 +309,7 @@ uint64_t HELPER(pshufb)(uint64_t src1, uint64_t src2, uint64_t src3)
|
|||
uint64_t HELPER(pmerge)(uint64_t src1, uint64_t src2, uint64_t src3)
|
||||
{
|
||||
vec64 r, s1, s2, s3;
|
||||
unsigned int i;
|
||||
int i;
|
||||
|
||||
s1.ud[0] = src1;
|
||||
s2.ud[0] = src2;
|
||||
|
@ -328,6 +365,83 @@ uint64_t HELPER(phminposuh)(uint64_t src1, uint64_t src2)
|
|||
return dst.ud[0];
|
||||
}
|
||||
|
||||
void HELPER(qpmpsadbh)(E2KReg *r, E2KReg *s1, uint32_t s2)
|
||||
{
|
||||
r->ud[0] = helper_mpsadbh(s1->ud[0], s2);
|
||||
r->ud[1] = helper_mpsadbh(s1->ud[1], s2);
|
||||
}
|
||||
|
||||
void HELPER(qpmulubhh)(E2KReg *r, uint64_t s1, E2KReg *s2)
|
||||
{
|
||||
r->ud[0] = helper_pmulubhh(s1 , s2->ud[0]);
|
||||
r->ud[1] = helper_pmulubhh(s1 >> 32, s2->ud[1]);
|
||||
}
|
||||
|
||||
uint64_t HELPER(qphminposuh)(E2KReg *s1, E2KReg *s2)
|
||||
{
|
||||
int i;
|
||||
uint16_t v = s1->uh[0];
|
||||
uint16_t p = 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (s1->uh[i] < v) {
|
||||
v = s1->uh[i];
|
||||
p = i;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (s2->uh[i] < v) {
|
||||
v = s2->uh[i];
|
||||
p = 8 + i;
|
||||
}
|
||||
}
|
||||
return ((uint64_t) p << 16) | v;
|
||||
}
|
||||
|
||||
uint32_t HELPER(qpsgn2mskb)(E2KReg *s2)
|
||||
{
|
||||
uint32_t r = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
r |= s2->sb[i] < 0 ? 1 << i : 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void HELPER(qpmsk2sgnb)(E2KReg *r, E2KReg *s1, uint32_t s2)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
r->ub[i] = s2 & (1 << i) ? s1->ub[i] | 0x80 : s1->ub[i] & 0x7f;
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(qppermb)(E2KReg *r, E2KReg *s1, E2KReg *s2, E2KReg *s3)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
uint8_t sel = s3->ub[i];
|
||||
int index = sel & 0x0f;
|
||||
uint8_t byte = sel & 0x10 ? s1->ub[index] : s2->ub[index];
|
||||
|
||||
byte = sel & 0x20 ? ~byte : byte;
|
||||
byte = sel & 0x40 ? reverse_bits(byte) : byte;
|
||||
byte = sel & 0x80 ? (byte & 0x80 ? 0xff : 0) : byte;
|
||||
|
||||
r->ub[i] = byte;
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(qpshufb)(E2KReg *r, E2KReg *s1, E2KReg *s2, E2KReg *s3)
|
||||
{
|
||||
r->ud[0] = helper_pshufb(s2->ud[1], s2->ud[0], s3->ud[0]);
|
||||
r->ud[1] = helper_pshufb(s1->ud[1], s1->ud[0], s3->ud[1]);
|
||||
}
|
||||
|
||||
static uint64_t get_value_from_truth_table(bool x, bool y, bool z, uint32_t truth_table)
|
||||
{
|
||||
int pos = x << 2 | y << 1 | z;
|
||||
|
@ -363,12 +477,15 @@ uint64_t HELPER(plog)(uint32_t opc, uint64_t src1, uint64_t src2, uint64_t src3)
|
|||
} \
|
||||
return dst.ud[0]; \
|
||||
}
|
||||
|
||||
#define GEN_ENV_HELPER_PACKED(name, type, code) \
|
||||
GEN_ENV_HELPER_PACKED_N(name, vec64_len(type), code)
|
||||
|
||||
#define GEN_ENV_HELPER_PACKED_OP(name, type, op) \
|
||||
GEN_ENV_HELPER_PACKED_N(name, vec64_len(type), { \
|
||||
dst.type[i] = op(env, s1.type[i], s2.type[i]); \
|
||||
})
|
||||
|
||||
#define GEN_ENV_HELPER_PACKED_HORIZONTAL_OP(name, type, op, map) \
|
||||
GEN_ENV_HELPER_PACKED_N(name, vec64_len(type) / 2, { \
|
||||
int j = i * 2; \
|
||||
|
@ -376,6 +493,31 @@ uint64_t HELPER(plog)(uint32_t opc, uint64_t src1, uint64_t src2, uint64_t src3)
|
|||
dst.type[i + vec64_len(type) / 2] = map(op(env, s2.type[j], s2.type[j + 1])); \
|
||||
})
|
||||
|
||||
#define IMPL_QPACKED_ENV_N(name, n, code) \
|
||||
void HELPER(name)(E2KReg *r, CPUE2KState *env, E2KReg *s1, E2KReg *s2) \
|
||||
{ \
|
||||
int i; \
|
||||
\
|
||||
for (i = 0; i < n; i++) { \
|
||||
code \
|
||||
} \
|
||||
}
|
||||
|
||||
#define IMPL_QPACKED_ENV(name, type, code) \
|
||||
IMPL_QPACKED_ENV_N(name, vec128_len(type), code)
|
||||
|
||||
#define IMPL_QPACKED_ENV_OP(name, type, op) \
|
||||
IMPL_QPACKED_ENV_N(name, vec128_len(type), { \
|
||||
r->type[i] = op(env, s1->type[i], s2->type[i]); \
|
||||
})
|
||||
|
||||
#define IMPL_QPACKED_ENV_HOP(name, type, op, map) \
|
||||
IMPL_QPACKED_ENV_N(name, vec128_len(type) / 2, { \
|
||||
int j = i * 2; \
|
||||
r->type[i ] = map(op(env, s1->type[j], s1->type[j + 1])); \
|
||||
r->type[i + vec128_len(type) / 2] = map(op(env, s2->type[j], s2->type[j + 1])); \
|
||||
})
|
||||
|
||||
GEN_ENV_HELPER_PACKED_OP(pfadds, uw, helper_fadds)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfsubs, uw, helper_fsubs)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfmuls, uw, helper_fmuls)
|
||||
|
@ -383,6 +525,8 @@ GEN_ENV_HELPER_PACKED_OP(pfmaxs, uw, helper_fmaxs)
|
|||
GEN_ENV_HELPER_PACKED_OP(pfmins, uw, helper_fmins)
|
||||
GEN_ENV_HELPER_PACKED_HORIZONTAL_OP(pfhadds, uw, helper_fadds, ident)
|
||||
GEN_ENV_HELPER_PACKED_HORIZONTAL_OP(pfhsubs, uw, helper_fsubs, ident)
|
||||
IMPL_QPACKED_ENV_HOP(qpfhadds, uw, helper_fadds, ident)
|
||||
IMPL_QPACKED_ENV_HOP(qpfhsubs, uw, helper_fsubs, ident)
|
||||
|
||||
GEN_ENV_HELPER_PACKED_OP(pfcmpeqs, uw, helper_fcmpeqs)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfcmplts, uw, helper_fcmplts)
|
||||
|
@ -428,3 +572,33 @@ GEN_ENV_HELPER_PACKED_OP_CVT(pfstoifs, uw, helper_fstoifs)
|
|||
GEN_ENV_HELPER_PACKED_UNARY_OP(pistofs, uw, helper_istofs)
|
||||
GEN_ENV_HELPER_PACKED_UNARY_OP(pfstois, uw, helper_fstois)
|
||||
GEN_ENV_HELPER_PACKED_UNARY_OP(pfstoistr, uw, helper_fstoistr)
|
||||
|
||||
#define IMPL_QPACKED_ENV_CVT_EXT(name, op) \
|
||||
void HELPER(name)(E2KReg *r, CPUE2KState *env, uint64_t src2) \
|
||||
{ \
|
||||
vec64 s2 = { .ud[0] = src2 }; \
|
||||
\
|
||||
r->ud[0] = op(env, s2.uw[0]); \
|
||||
r->ud[1] = op(env, s2.uw[1]); \
|
||||
}
|
||||
|
||||
IMPL_QPACKED_ENV_CVT_EXT(qpfstoid, helper_fstoid)
|
||||
IMPL_QPACKED_ENV_CVT_EXT(qpfstoidtr, helper_fstoidtr)
|
||||
IMPL_QPACKED_ENV_CVT_EXT(qpistofd, helper_istofd)
|
||||
IMPL_QPACKED_ENV_CVT_EXT(qpfstofd, helper_fstofd)
|
||||
|
||||
#define IMPL_QPACKED_ENV_CVT_TRUNC(name, op) \
|
||||
uint64_t HELPER(name)(CPUE2KState *env, E2KReg *s2) \
|
||||
{ \
|
||||
vec64 r; \
|
||||
\
|
||||
r.uw[0] = op(env, s2->ud[0]); \
|
||||
r.uw[1] = op(env, s2->ud[1]); \
|
||||
\
|
||||
return r.ud[0]; \
|
||||
}
|
||||
|
||||
IMPL_QPACKED_ENV_CVT_TRUNC(qpfdtois, helper_fdtois)
|
||||
IMPL_QPACKED_ENV_CVT_TRUNC(qpfdtoistr, helper_fdtoistr)
|
||||
IMPL_QPACKED_ENV_CVT_TRUNC(qpidtofs, helper_idtofs)
|
||||
IMPL_QPACKED_ENV_CVT_TRUNC(qpfdtofs, helper_fdtofs)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue