⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 translate.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
/* *  CRIS emulation for qemu: main translation routines. * *  Copyright (c) 2007 AXIS Communications AB *  Written by Edgar E. Iglesias. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* * This file implements a CRIS decoder-stage in SW. The decoder translates the * guest (CRIS) machine-code into host machine code via dyngen using the * micro-operations described in op.c * * The micro-operations for CRIS translation implement a RISC style ISA. * Note that the micro-operations typically order their operands * starting with the dst. CRIS asm, does the opposite. * * For example the following CRIS code: * add.d [$r0], $r1 * * translates into: * * gen_movl_T0_reg(0);   // Fetch $r0 into T0 * gen_load_T0_T0();     // Load T0, @T0 * gen_movl_reg_T0(1);   // Writeback T0 into $r1 * * The actual names for the micro-code generators vary but the example * illustrates the point. */#include <stdarg.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <inttypes.h>#include <assert.h>#include "cpu.h"#include "exec-all.h"#include "disas.h"#include "crisv32-decode.h"#define CRIS_STATS 0#if CRIS_STATS#define STATS(x) x#else#define STATS(x)#endif#define DISAS_CRIS 0#if DISAS_CRIS#define DIS(x) x#else#define DIS(x)#endif#ifdef USE_DIRECT_JUMP#define TBPARAM(x)#else#define TBPARAM(x) (long)(x)#endif#define BUG() (gen_BUG(dc, __FILE__, __LINE__))#define BUG_ON(x) ({if (x) BUG();})/* Used by the decoder.  */#define EXTRACT_FIELD(src, start, end) \            (((src) >> start) & ((1 << (end - start + 1)) - 1))#define CC_MASK_NZ 0xc#define CC_MASK_NZV 0xe#define CC_MASK_NZVC 0xf#define CC_MASK_RNZV 0x10estatic uint16_t *gen_opc_ptr;static uint32_t *gen_opparam_ptr;enum {#define DEF(s, n, copy_size) INDEX_op_ ## s,#include "opc.h"#undef DEF    NB_OPS,};#include "gen-op.h"/* This is the state at translation time.  */typedef struct DisasContext {	CPUState *env;	target_ulong pc, insn_pc;	/* Decoder.  */	uint32_t ir;	uint32_t opcode;	unsigned int op1;	unsigned int op2;	unsigned int zsize, zzsize;	unsigned int mode;	unsigned int postinc;	struct	{		int op;		int size;		unsigned int mask;	} cc_state[3];	int cc_i;	int update_cc;	int cc_op;	int cc_size;	uint32_t cc_mask;	int flags_live;	int flagx_live;	int flags_x;	uint32_t tb_entry_flags;	int memidx; /* user or kernel mode.  */	int is_jmp;	int dyn_jmp;	uint32_t delayed_pc;	int delayed_branch;	int bcc;	uint32_t condlabel;	struct TranslationBlock *tb;	int singlestep_enabled;} DisasContext;void cris_prepare_jmp (DisasContext *dc, uint32_t dst);static void gen_BUG(DisasContext *dc, char *file, int line){	printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);	fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);	cpu_dump_state (dc->env, stdout, fprintf, 0);	fflush(NULL);	cris_prepare_jmp (dc, 0x70000000 + line);}/* Table to generate quick moves from T0 onto any register.  */static GenOpFunc *gen_movl_reg_T0[16] ={	gen_op_movl_r0_T0, gen_op_movl_r1_T0,	gen_op_movl_r2_T0, gen_op_movl_r3_T0,	gen_op_movl_r4_T0, gen_op_movl_r5_T0,	gen_op_movl_r6_T0, gen_op_movl_r7_T0,	gen_op_movl_r8_T0, gen_op_movl_r9_T0,	gen_op_movl_r10_T0, gen_op_movl_r11_T0,	gen_op_movl_r12_T0, gen_op_movl_r13_T0,	gen_op_movl_r14_T0, gen_op_movl_r15_T0,};static GenOpFunc *gen_movl_T0_reg[16] ={	gen_op_movl_T0_r0, gen_op_movl_T0_r1,	gen_op_movl_T0_r2, gen_op_movl_T0_r3,	gen_op_movl_T0_r4, gen_op_movl_T0_r5,	gen_op_movl_T0_r6, gen_op_movl_T0_r7,	gen_op_movl_T0_r8, gen_op_movl_T0_r9,	gen_op_movl_T0_r10, gen_op_movl_T0_r11,	gen_op_movl_T0_r12, gen_op_movl_T0_r13,	gen_op_movl_T0_r14, gen_op_movl_T0_r15,};static void noop_write(void) {	/* nop.  */}static void gen_vr_read(void) {	gen_op_movl_T0_im(32);}static void gen_ccs_read(void) {	gen_op_movl_T0_p13();}static void gen_ccs_write(void) {	gen_op_movl_p13_T0();}/* Table to generate quick moves from T0 onto any register.  */static GenOpFunc *gen_movl_preg_T0[16] ={	noop_write,  /* bz, not writeable.  */	noop_write,  /* vr, not writeable.  */	gen_op_movl_p2_T0, gen_op_movl_p3_T0,	noop_write,  /* wz, not writeable.  */	gen_op_movl_p5_T0,	gen_op_movl_p6_T0, gen_op_movl_p7_T0,	noop_write,  /* dz, not writeable.  */	gen_op_movl_p9_T0,	gen_op_movl_p10_T0, gen_op_movl_p11_T0,	gen_op_movl_p12_T0,	gen_ccs_write, /* ccs needs special treatment.  */	gen_op_movl_p14_T0, gen_op_movl_p15_T0,};static GenOpFunc *gen_movl_T0_preg[16] ={	gen_op_movl_T0_p0,	gen_vr_read,	gen_op_movl_T0_p2, gen_op_movl_T0_p3,	gen_op_movl_T0_p4, gen_op_movl_T0_p5,	gen_op_movl_T0_p6, gen_op_movl_T0_p7,	gen_op_movl_T0_p8, gen_op_movl_T0_p9,	gen_op_movl_T0_p10, gen_op_movl_T0_p11,	gen_op_movl_T0_p12,	gen_ccs_read, /* ccs needs special treatment.  */	gen_op_movl_T0_p14, gen_op_movl_T0_p15,};/* We need this table to handle moves with implicit width.  */int preg_sizes[] = {	1, /* bz.  */	1, /* vr.  */	4, /* pid.  */	1, /* srs.  */	2, /* wz.  */	4, 4, 4,	4, 4, 4, 4,	4, 4, 4, 4,};#ifdef CONFIG_USER_ONLY#define GEN_OP_LD(width, reg) \  void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \    gen_op_ld##width##_T0_##reg##_raw(); \  }#define GEN_OP_ST(width, reg) \  void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \    gen_op_st##width##_##reg##_T1_raw(); \  }#else#define GEN_OP_LD(width, reg) \  void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \    if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \    else gen_op_ld##width##_T0_##reg##_user();\  }#define GEN_OP_ST(width, reg) \  void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \    if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \    else gen_op_st##width##_##reg##_T1_user();\  }#endifGEN_OP_LD(ub, T0)GEN_OP_LD(b, T0)GEN_OP_ST(b, T0)GEN_OP_LD(uw, T0)GEN_OP_LD(w, T0)GEN_OP_ST(w, T0)GEN_OP_LD(l, T0)GEN_OP_ST(l, T0)static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest){	TranslationBlock *tb;	tb = dc->tb;	if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {		if (n == 0)			gen_op_goto_tb0(TBPARAM(tb));		else			gen_op_goto_tb1(TBPARAM(tb));		gen_op_movl_T0_0();	} else {		gen_op_movl_T0_0();	}	gen_op_exit_tb();}/* Sign extend at translation time.  */static int sign_extend(unsigned int val, unsigned int width){	int sval;	/* LSL.  */	val <<= 31 - width;	sval = val;	/* ASR.  */	sval >>= 31 - width;	return sval;}static void cris_evaluate_flags(DisasContext *dc){	if (!dc->flags_live) {		switch (dc->cc_op)		{			case CC_OP_MCP:				gen_op_evaluate_flags_mcp ();				break;			case CC_OP_MULS:				gen_op_evaluate_flags_muls ();				break;			case CC_OP_MULU:				gen_op_evaluate_flags_mulu ();				break;			case CC_OP_MOVE:				switch (dc->cc_size)				{					case 4:						gen_op_evaluate_flags_move_4();						break;					case 2:						gen_op_evaluate_flags_move_2();						break;					default:						gen_op_evaluate_flags ();						break;				}				break;			default:			{				switch (dc->cc_size)				{					case 4:						gen_op_evaluate_flags_alu_4 ();						break;					default:						gen_op_evaluate_flags ();						break;				}			}			break;		}		dc->flags_live = 1;	}}static void cris_cc_mask(DisasContext *dc, unsigned int mask){	uint32_t ovl;	ovl = (dc->cc_mask ^ mask) & ~mask;	if (ovl) {		/* TODO: optimize this case. It trigs all the time.  */		cris_evaluate_flags (dc);	}	dc->cc_mask = mask;	dc->update_cc = 1;	if (mask == 0)		dc->update_cc = 0;	else {		gen_op_update_cc_mask(mask);		dc->flags_live = 0;	}}static void cris_update_cc_op(DisasContext *dc, int op){	dc->cc_op = op;	gen_op_update_cc_op(op);	dc->flags_live = 0;}static void cris_update_cc_size(DisasContext *dc, int size){	dc->cc_size = size;	gen_op_update_cc_size_im(size);}/* op is the operation.   T0, T1 are the operands.   dst is the destination reg.*/static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size){	int writeback = 1;	if (dc->update_cc) {		cris_update_cc_op(dc, op);		cris_update_cc_size(dc, size);		gen_op_update_cc_x(dc->flagx_live, dc->flags_x);		gen_op_update_cc_dest_T0();	}	/* Emit the ALU insns.  */	switch (op)	{		case CC_OP_ADD:			gen_op_addl_T0_T1();			/* Extended arithmetics.  */			if (!dc->flagx_live)				gen_op_addxl_T0_C();			else if (dc->flags_x)				gen_op_addxl_T0_C();			break;		case CC_OP_ADDC:			gen_op_addl_T0_T1();			gen_op_addl_T0_C();			break;		case CC_OP_MCP:			gen_op_addl_T0_T1();			gen_op_addl_T0_R();			break;		case CC_OP_SUB:			gen_op_negl_T1_T1();			gen_op_addl_T0_T1();			/* CRIS flag evaluation needs ~src.  */			gen_op_negl_T1_T1();			gen_op_not_T1_T1();			/* Extended arithmetics.  */			if (!dc->flagx_live)				gen_op_subxl_T0_C();			else if (dc->flags_x)				gen_op_subxl_T0_C();			break;		case CC_OP_MOVE:			gen_op_movl_T0_T1();			break;		case CC_OP_OR:			gen_op_orl_T0_T1();			break;		case CC_OP_AND:			gen_op_andl_T0_T1();			break;		case CC_OP_XOR:			gen_op_xorl_T0_T1();			break;		case CC_OP_LSL:			gen_op_lsll_T0_T1();			break;		case CC_OP_LSR:			gen_op_lsrl_T0_T1();			break;		case CC_OP_ASR:			gen_op_asrl_T0_T1();			break;		case CC_OP_NEG:			gen_op_negl_T0_T1();			/* Extended arithmetics.  */			gen_op_subxl_T0_C();			break;		case CC_OP_LZ:			gen_op_lz_T0_T1();			break;		case CC_OP_BTST:			gen_op_btst_T0_T1();			writeback = 0;			break;		case CC_OP_MULS:			gen_op_muls_T0_T1();			break;		case CC_OP_MULU:			gen_op_mulu_T0_T1();			break;		case CC_OP_DSTEP:			gen_op_dstep_T0_T1();			break;		case CC_OP_BOUND:			gen_op_bound_T0_T1();			break;		case CC_OP_CMP:			gen_op_negl_T1_T1();			gen_op_addl_T0_T1();			/* CRIS flag evaluation needs ~src.  */			gen_op_negl_T1_T1();			gen_op_not_T1_T1();			/* Extended arithmetics.  */			gen_op_subxl_T0_C();			writeback = 0;			break;		default:			fprintf (logfile, "illegal ALU op.\n");			BUG();			break;	}	if (dc->update_cc)		gen_op_update_cc_src_T1();	if (size == 1)		gen_op_andl_T0_im(0xff);	else if (size == 2)		gen_op_andl_T0_im(0xffff);	/* Writeback.  */	if (writeback) {		if (size == 4)			gen_movl_reg_T0[rd]();		else {			gen_op_movl_T1_T0();			gen_movl_T0_reg[rd]();			if (size == 1)				gen_op_andl_T0_im(~0xff);			else				gen_op_andl_T0_im(~0xffff);			gen_op_orl_T0_T1();			gen_movl_reg_T0[rd]();			gen_op_movl_T0_T1();		}	}	if (dc->update_cc)		gen_op_update_cc_result_T0();	{		/* TODO: Optimize this.  */		if (!dc->flagx_live)			cris_evaluate_flags(dc);	}}static int arith_cc(DisasContext *dc){	if (dc->update_cc) {		switch (dc->cc_op) {			case CC_OP_ADD: return 1;			case CC_OP_SUB: return 1;			case CC_OP_LSL: return 1;			case CC_OP_LSR: return 1;			case CC_OP_ASR: return 1;			case CC_OP_CMP: return 1;			default:				return 0;		}	}	return 0;}static void gen_tst_cc (DisasContext *dc, int cond){	int arith_opt;	/* TODO: optimize more condition codes.  */	arith_opt = arith_cc(dc) && !dc->flags_live;	switch (cond) {		case CC_EQ:			if (arith_opt)				gen_op_tst_cc_eq_fast ();			else {				cris_evaluate_flags(dc);				gen_op_tst_cc_eq ();			}			break;		case CC_NE:			if (arith_opt)				gen_op_tst_cc_ne_fast ();			else {				cris_evaluate_flags(dc);				gen_op_tst_cc_ne ();			}			break;		case CC_CS:			cris_evaluate_flags(dc);			gen_op_tst_cc_cs ();			break;		case CC_CC:			cris_evaluate_flags(dc);			gen_op_tst_cc_cc ();			break;		case CC_VS:			cris_evaluate_flags(dc);			gen_op_tst_cc_vs ();			break;		case CC_VC:			cris_evaluate_flags(dc);			gen_op_tst_cc_vc ();			break;		case CC_PL:			if (arith_opt)				gen_op_tst_cc_pl_fast ();			else {				cris_evaluate_flags(dc);				gen_op_tst_cc_pl ();			}			break;		case CC_MI:			if (arith_opt)				gen_op_tst_cc_mi_fast ();			else {				cris_evaluate_flags(dc);				gen_op_tst_cc_mi ();			}			break;		case CC_LS:			cris_evaluate_flags(dc);			gen_op_tst_cc_ls ();			break;		case CC_HI:			cris_evaluate_flags(dc);			gen_op_tst_cc_hi ();			break;		case CC_GE:			cris_evaluate_flags(dc);			gen_op_tst_cc_ge ();			break;		case CC_LT:			cris_evaluate_flags(dc);			gen_op_tst_cc_lt ();			break;		case CC_GT:			cris_evaluate_flags(dc);			gen_op_tst_cc_gt ();			break;		case CC_LE:			cris_evaluate_flags(dc);			gen_op_tst_cc_le ();			break;		case CC_P:			cris_evaluate_flags(dc);			gen_op_tst_cc_p ();			break;		case CC_A:			cris_evaluate_flags(dc);			gen_op_movl_T0_im (1);			break;		default:			BUG();			break;	};}static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -