mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-12 07:32:19 +00:00
CRIS: Restructure the translator to allow for better code generation.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4594 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
9bcd77d6b1
commit
30abcfc7ba
@ -120,8 +120,7 @@ typedef struct CPUCRISState {
|
|||||||
uint32_t cc_result;
|
uint32_t cc_result;
|
||||||
/* size of the operation, 1 = byte, 2 = word, 4 = dword. */
|
/* size of the operation, 1 = byte, 2 = word, 4 = dword. */
|
||||||
int cc_size;
|
int cc_size;
|
||||||
/* Extended arithmetics. */
|
/* X flag at the time of cc snapshot. */
|
||||||
int cc_x_live;
|
|
||||||
int cc_x;
|
int cc_x;
|
||||||
|
|
||||||
int exception_index;
|
int exception_index;
|
||||||
@ -130,10 +129,6 @@ typedef struct CPUCRISState {
|
|||||||
int fault_vector;
|
int fault_vector;
|
||||||
int trap_vector;
|
int trap_vector;
|
||||||
|
|
||||||
uint32_t debug1;
|
|
||||||
uint32_t debug2;
|
|
||||||
uint32_t debug3;
|
|
||||||
|
|
||||||
/* FIXME: add a check in the translator to avoid writing to support
|
/* FIXME: add a check in the translator to avoid writing to support
|
||||||
register sets beyond the 4th. The ISA allows up to 256! but in
|
register sets beyond the 4th. The ISA allows up to 256! but in
|
||||||
practice there is no core that implements more than 4.
|
practice there is no core that implements more than 4.
|
||||||
@ -177,20 +172,14 @@ void do_interrupt(CPUCRISState *env);
|
|||||||
is returned if the signal was handled by the virtual CPU. */
|
is returned if the signal was handled by the virtual CPU. */
|
||||||
int cpu_cris_signal_handler(int host_signum, void *pinfo,
|
int cpu_cris_signal_handler(int host_signum, void *pinfo,
|
||||||
void *puc);
|
void *puc);
|
||||||
void cpu_cris_flush_flags(CPUCRISState *, int);
|
|
||||||
|
|
||||||
|
|
||||||
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
||||||
int is_asi);
|
int is_asi);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CC_OP_DYNAMIC, /* Use env->cc_op */
|
CC_OP_DYNAMIC, /* Use env->cc_op */
|
||||||
CC_OP_FLAGS,
|
CC_OP_FLAGS,
|
||||||
CC_OP_LOGIC,
|
|
||||||
CC_OP_CMP,
|
CC_OP_CMP,
|
||||||
CC_OP_MOVE,
|
CC_OP_MOVE,
|
||||||
CC_OP_MOVE_PD,
|
|
||||||
CC_OP_MOVE_SD,
|
|
||||||
CC_OP_ADD,
|
CC_OP_ADD,
|
||||||
CC_OP_ADDC,
|
CC_OP_ADDC,
|
||||||
CC_OP_MCP,
|
CC_OP_MCP,
|
||||||
@ -213,32 +202,6 @@ enum {
|
|||||||
CC_OP_LZ
|
CC_OP_LZ
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CCF_C 0x01
|
|
||||||
#define CCF_V 0x02
|
|
||||||
#define CCF_Z 0x04
|
|
||||||
#define CCF_N 0x08
|
|
||||||
#define CCF_X 0x10
|
|
||||||
|
|
||||||
#define CRIS_SSP 0
|
|
||||||
#define CRIS_USP 1
|
|
||||||
|
|
||||||
void cris_set_irq_level(CPUCRISState *env, int level, uint8_t vector);
|
|
||||||
void cris_set_macsr(CPUCRISState *env, uint32_t val);
|
|
||||||
void cris_switch_sp(CPUCRISState *env);
|
|
||||||
|
|
||||||
void do_cris_semihosting(CPUCRISState *env, int nr);
|
|
||||||
|
|
||||||
enum cris_features {
|
|
||||||
CRIS_FEATURE_CF_ISA_MUL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline int cris_feature(CPUCRISState *env, int feature)
|
|
||||||
{
|
|
||||||
return (env->features & (1u << feature)) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void register_cris_insns (CPUCRISState *env);
|
|
||||||
|
|
||||||
/* CRIS uses 8k pages. */
|
/* CRIS uses 8k pages. */
|
||||||
#define TARGET_PAGE_BITS 13
|
#define TARGET_PAGE_BITS 13
|
||||||
#define MMAP_SHIFT TARGET_PAGE_BITS
|
#define MMAP_SHIFT TARGET_PAGE_BITS
|
||||||
|
@ -42,9 +42,8 @@ int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
|
|||||||
int mmu_idx, int is_softmmu)
|
int mmu_idx, int is_softmmu)
|
||||||
{
|
{
|
||||||
env->exception_index = 0xaa;
|
env->exception_index = 0xaa;
|
||||||
env->debug1 = address;
|
env->pregs[PR_EDA] = address;
|
||||||
cpu_dump_state(env, stderr, fprintf, 0);
|
cpu_dump_state(env, stderr, fprintf, 0);
|
||||||
env->pregs[PR_ERP] = env->pc;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
void TCG_HELPER_PROTO helper_raise_exception(uint32_t index);
|
void TCG_HELPER_PROTO helper_raise_exception(uint32_t index);
|
||||||
void TCG_HELPER_PROTO helper_tlb_flush_pid(uint32_t pid);
|
void TCG_HELPER_PROTO helper_tlb_flush_pid(uint32_t pid);
|
||||||
void TCG_HELPER_PROTO helper_tlb_flush(void);
|
|
||||||
void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2);
|
void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2);
|
||||||
void TCG_HELPER_PROTO helper_dummy(void);
|
void TCG_HELPER_PROTO helper_dummy(void);
|
||||||
void TCG_HELPER_PROTO helper_rfe(void);
|
void TCG_HELPER_PROTO helper_rfe(void);
|
||||||
@ -18,3 +17,4 @@ void TCG_HELPER_PROTO helper_evaluate_flags_alu_4(void);
|
|||||||
void TCG_HELPER_PROTO helper_evaluate_flags_move_4 (void);
|
void TCG_HELPER_PROTO helper_evaluate_flags_move_4 (void);
|
||||||
void TCG_HELPER_PROTO helper_evaluate_flags_move_2 (void);
|
void TCG_HELPER_PROTO helper_evaluate_flags_move_2 (void);
|
||||||
void TCG_HELPER_PROTO helper_evaluate_flags (void);
|
void TCG_HELPER_PROTO helper_evaluate_flags (void);
|
||||||
|
void TCG_HELPER_PROTO helper_top_evaluate_flags(void);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "exec.h"
|
#include "exec.h"
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
|
#include "helper.h"
|
||||||
|
|
||||||
#define MMUSUFFIX _mmu
|
#define MMUSUFFIX _mmu
|
||||||
|
|
||||||
@ -67,6 +68,9 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
|
|||||||
/* the PC is inside the translated code. It means that we have
|
/* the PC is inside the translated code. It means that we have
|
||||||
a virtual CPU fault */
|
a virtual CPU fault */
|
||||||
cpu_restore_state(tb, env, pc, NULL);
|
cpu_restore_state(tb, env, pc, NULL);
|
||||||
|
|
||||||
|
/* Evaluate flags after retranslation. */
|
||||||
|
helper_top_evaluate_flags();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cpu_loop_exit();
|
cpu_loop_exit();
|
||||||
@ -87,12 +91,7 @@ void helper_tlb_flush_pid(uint32_t pid)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_tlb_flush(void)
|
void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2)
|
||||||
{
|
|
||||||
tlb_flush(env, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void helper_dump(uint32_t a0, uint32_t a1)
|
|
||||||
{
|
{
|
||||||
(fprintf(logfile, "%s: a0=%x a1=%x\n", __func__, a0, a1));
|
(fprintf(logfile, "%s: a0=%x a1=%x\n", __func__, a0, a1));
|
||||||
}
|
}
|
||||||
@ -236,13 +235,7 @@ static void evaluate_flags_writeback(uint32_t flags)
|
|||||||
int x;
|
int x;
|
||||||
|
|
||||||
/* Extended arithmetics, leave the z flag alone. */
|
/* Extended arithmetics, leave the z flag alone. */
|
||||||
env->debug3 = env->pregs[PR_CCS];
|
x = env->cc_x;
|
||||||
|
|
||||||
if (env->cc_x_live)
|
|
||||||
x = env->cc_x;
|
|
||||||
else
|
|
||||||
x = env->pregs[PR_CCS] & X_FLAG;
|
|
||||||
|
|
||||||
if ((x || env->cc_op == CC_OP_ADDC)
|
if ((x || env->cc_op == CC_OP_ADDC)
|
||||||
&& flags & Z_FLAG)
|
&& flags & Z_FLAG)
|
||||||
env->cc_mask &= ~Z_FLAG;
|
env->cc_mask &= ~Z_FLAG;
|
||||||
@ -359,7 +352,23 @@ void helper_evaluate_flags_alu_4(void)
|
|||||||
|
|
||||||
src = env->cc_src;
|
src = env->cc_src;
|
||||||
dst = env->cc_dest;
|
dst = env->cc_dest;
|
||||||
res = env->cc_result;
|
|
||||||
|
/* Reconstruct the result. */
|
||||||
|
switch (env->cc_op)
|
||||||
|
{
|
||||||
|
case CC_OP_SUB:
|
||||||
|
res = dst - src;
|
||||||
|
break;
|
||||||
|
case CC_OP_ADD:
|
||||||
|
res = dst + src;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = env->cc_result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP)
|
||||||
|
src = ~src;
|
||||||
|
|
||||||
if ((res & 0x80000000L) != 0L)
|
if ((res & 0x80000000L) != 0L)
|
||||||
{
|
{
|
||||||
@ -396,11 +405,9 @@ void helper_evaluate_flags_alu_4(void)
|
|||||||
|
|
||||||
void helper_evaluate_flags_move_4 (void)
|
void helper_evaluate_flags_move_4 (void)
|
||||||
{
|
{
|
||||||
uint32_t src;
|
|
||||||
uint32_t res;
|
uint32_t res;
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
|
|
||||||
src = env->cc_src;
|
|
||||||
res = env->cc_result;
|
res = env->cc_result;
|
||||||
|
|
||||||
if ((int32_t)res < 0)
|
if ((int32_t)res < 0)
|
||||||
@ -440,6 +447,8 @@ void helper_evaluate_flags (void)
|
|||||||
dst = env->cc_dest;
|
dst = env->cc_dest;
|
||||||
res = env->cc_result;
|
res = env->cc_result;
|
||||||
|
|
||||||
|
if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP)
|
||||||
|
src = ~src;
|
||||||
|
|
||||||
/* Now, evaluate the flags. This stuff is based on
|
/* Now, evaluate the flags. This stuff is based on
|
||||||
Per Zander's CRISv10 simulator. */
|
Per Zander's CRISv10 simulator. */
|
||||||
@ -548,3 +557,55 @@ void helper_evaluate_flags (void)
|
|||||||
}
|
}
|
||||||
evaluate_flags_writeback(flags);
|
evaluate_flags_writeback(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void helper_top_evaluate_flags(void)
|
||||||
|
{
|
||||||
|
switch (env->cc_op)
|
||||||
|
{
|
||||||
|
case CC_OP_MCP:
|
||||||
|
helper_evaluate_flags_mcp();
|
||||||
|
break;
|
||||||
|
case CC_OP_MULS:
|
||||||
|
helper_evaluate_flags_muls();
|
||||||
|
break;
|
||||||
|
case CC_OP_MULU:
|
||||||
|
helper_evaluate_flags_mulu();
|
||||||
|
break;
|
||||||
|
case CC_OP_MOVE:
|
||||||
|
case CC_OP_AND:
|
||||||
|
case CC_OP_OR:
|
||||||
|
case CC_OP_XOR:
|
||||||
|
case CC_OP_ASR:
|
||||||
|
case CC_OP_LSR:
|
||||||
|
case CC_OP_LSL:
|
||||||
|
switch (env->cc_size)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
helper_evaluate_flags_move_4();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
helper_evaluate_flags_move_2();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
helper_evaluate_flags();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CC_OP_FLAGS:
|
||||||
|
/* live. */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
switch (env->cc_size)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
helper_evaluate_flags_alu_4();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
helper_evaluate_flags();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user