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;
|
||||
/* size of the operation, 1 = byte, 2 = word, 4 = dword. */
|
||||
int cc_size;
|
||||
/* Extended arithmetics. */
|
||||
int cc_x_live;
|
||||
/* X flag at the time of cc snapshot. */
|
||||
int cc_x;
|
||||
|
||||
int exception_index;
|
||||
@ -130,10 +129,6 @@ typedef struct CPUCRISState {
|
||||
int fault_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
|
||||
register sets beyond the 4th. The ISA allows up to 256! but in
|
||||
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. */
|
||||
int cpu_cris_signal_handler(int host_signum, void *pinfo,
|
||||
void *puc);
|
||||
void cpu_cris_flush_flags(CPUCRISState *, int);
|
||||
|
||||
|
||||
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
||||
int is_asi);
|
||||
|
||||
enum {
|
||||
CC_OP_DYNAMIC, /* Use env->cc_op */
|
||||
CC_OP_FLAGS,
|
||||
CC_OP_LOGIC,
|
||||
CC_OP_CMP,
|
||||
CC_OP_MOVE,
|
||||
CC_OP_MOVE_PD,
|
||||
CC_OP_MOVE_SD,
|
||||
CC_OP_ADD,
|
||||
CC_OP_ADDC,
|
||||
CC_OP_MCP,
|
||||
@ -213,32 +202,6 @@ enum {
|
||||
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. */
|
||||
#define TARGET_PAGE_BITS 13
|
||||
#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)
|
||||
{
|
||||
env->exception_index = 0xaa;
|
||||
env->debug1 = address;
|
||||
env->pregs[PR_EDA] = address;
|
||||
cpu_dump_state(env, stderr, fprintf, 0);
|
||||
env->pregs[PR_ERP] = env->pc;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
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(void);
|
||||
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_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_2 (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 "exec.h"
|
||||
#include "mmu.h"
|
||||
#include "helper.h"
|
||||
|
||||
#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
|
||||
a virtual CPU fault */
|
||||
cpu_restore_state(tb, env, pc, NULL);
|
||||
|
||||
/* Evaluate flags after retranslation. */
|
||||
helper_top_evaluate_flags();
|
||||
}
|
||||
}
|
||||
cpu_loop_exit();
|
||||
@ -87,12 +91,7 @@ void helper_tlb_flush_pid(uint32_t pid)
|
||||
#endif
|
||||
}
|
||||
|
||||
void helper_tlb_flush(void)
|
||||
{
|
||||
tlb_flush(env, 1);
|
||||
}
|
||||
|
||||
void helper_dump(uint32_t a0, uint32_t a1)
|
||||
void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2)
|
||||
{
|
||||
(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;
|
||||
|
||||
/* Extended arithmetics, leave the z flag alone. */
|
||||
env->debug3 = env->pregs[PR_CCS];
|
||||
|
||||
if (env->cc_x_live)
|
||||
x = env->cc_x;
|
||||
else
|
||||
x = env->pregs[PR_CCS] & X_FLAG;
|
||||
|
||||
x = env->cc_x;
|
||||
if ((x || env->cc_op == CC_OP_ADDC)
|
||||
&& flags & Z_FLAG)
|
||||
env->cc_mask &= ~Z_FLAG;
|
||||
@ -359,7 +352,23 @@ void helper_evaluate_flags_alu_4(void)
|
||||
|
||||
src = env->cc_src;
|
||||
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)
|
||||
{
|
||||
@ -396,11 +405,9 @@ void helper_evaluate_flags_alu_4(void)
|
||||
|
||||
void helper_evaluate_flags_move_4 (void)
|
||||
{
|
||||
uint32_t src;
|
||||
uint32_t res;
|
||||
uint32_t flags = 0;
|
||||
|
||||
src = env->cc_src;
|
||||
res = env->cc_result;
|
||||
|
||||
if ((int32_t)res < 0)
|
||||
@ -440,6 +447,8 @@ void helper_evaluate_flags (void)
|
||||
dst = env->cc_dest;
|
||||
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
|
||||
Per Zander's CRISv10 simulator. */
|
||||
@ -548,3 +557,55 @@ void helper_evaluate_flags (void)
|
||||
}
|
||||
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…
Reference in New Issue
Block a user