?? gencpu.c
字號:
/* * UAE - The Un*x Amiga Emulator * * MC68000 emulation generator * * This is a fairly stupid program that generates a lot of case labels that * can be #included in a switch statement. * As an alternative, it can generate functions that handle specific * MC68000 instructions, plus a prototype header file and a function pointer * array to look up the function for an opcode. * Error checking is bad, an illegal table68k file will cause the program to * call abort(). * The generated code is sometimes sub-optimal, an optimizing compiler should * take care of this. * * (c) 1995 Bernd Schmidt * */#include "sysdeps.h"#include <ctype.h>#include "readcpu.h"#define BOOL_TYPE "int"long int counts[65536];static int isspecific(int opcode){ return counts[opcode]>5;}static void read_counts(void){ FILE *file; unsigned long opcode,count, total; int trapcount=0; int trap=0; memset(counts, 0, sizeof counts); file=fopen("insncount","r"); if(file) { fscanf(file,"Total: %d",&total); while(fscanf(file,"%x: %d\n",&opcode,&count)==2) { counts[opcode]=10000.0*count/total; if(isspecific(opcode)) { trapcount+=count; trap++; } }#if 0 fprintf(stderr,"trap %d function: %f%\n",trap,100.0*trapcount/total);#endif }}static int n_braces = 0;static void start_brace(void){ n_braces++; printf("{");}static void close_brace(void){ assert (n_braces > 0); n_braces--; printf("}");}static void finish_braces(void){ while (n_braces > 0) close_brace();}static void pop_braces(int to){ while (n_braces > to) close_brace();}static void genamode(amodes mode, char *reg, wordsizes size, char *name, int getv, int movem){ start_brace (); switch(mode) { case Dreg: if (movem) abort(); if (getv) switch(size) { case sz_byte: printf("\tBYTE %s = regs.d[%s];\n", name, reg); break; case sz_word: printf("\tWORD %s = regs.d[%s];\n", name, reg); break; case sz_long: printf("\tLONG %s = regs.d[%s];\n", name, reg); break; default: abort(); } break; case Areg: if (movem) abort(); if (getv) switch(size) { case sz_word: printf("\tWORD %s = regs.a[%s];\n", name, reg); break; case sz_long: printf("\tLONG %s = regs.a[%s];\n", name, reg); break; default: abort(); } break; case Aind: printf("\tCPTR %sa = regs.a[%s];\n", name, reg); if (getv) switch(size) { case sz_byte: printf("\tBYTE %s = get_byte(%sa);\n", name, name); break; case sz_word: printf("\tWORD %s = get_word(%sa);\n", name, name); break; case sz_long: printf("\tLONG %s = get_long(%sa);\n", name, name); break; default: abort(); } break; case Aipi: printf("\tCPTR %sa = regs.a[%s];\n", name, reg); switch(size) { case sz_byte: if (getv) printf("\tBYTE %s = get_byte(%sa);\n", name, name); if (!movem) { start_brace(); printf("\tregs.a[%s] += areg_byteinc[%s];\n", reg, reg); } break; case sz_word: if (getv) printf("\tWORD %s = get_word(%sa);\n", name, name); if (!movem) { start_brace(); printf("\tregs.a[%s] += 2;\n", reg); } break; case sz_long: if (getv) printf("\tLONG %s = get_long(%sa);\n", name, name); if (!movem) { start_brace(); printf("\tregs.a[%s] += 4;\n", reg); } break; default: abort(); } break; case Apdi: switch(size) { case sz_byte: if (!movem) printf("\tregs.a[%s] -= areg_byteinc[%s];\n", reg, reg); start_brace(); printf("\tCPTR %sa = regs.a[%s];\n", name, reg); if (getv) printf("\tBYTE %s = get_byte(%sa);\n", name, name); break; case sz_word: if (!movem) printf("\tregs.a[%s] -= 2;\n", reg); start_brace(); printf("\tCPTR %sa = regs.a[%s];\n", name, reg); if (getv) printf("\tWORD %s = get_word(%sa);\n", name, name); break; case sz_long: if (!movem) printf("\tregs.a[%s] -= 4;\n", reg); start_brace(); printf("\tCPTR %sa = regs.a[%s];\n", name, reg); if (getv) printf("\tLONG %s = get_long(%sa);\n", name, name); break; default: abort(); } break; case Ad16: printf("\tCPTR %sa = regs.a[%s] + (LONG)(WORD)nextiword();\n", name, reg); if (getv) switch(size) { case sz_byte: printf("\tBYTE %s = get_byte(%sa);\n", name, name); break; case sz_word: printf("\tWORD %s = get_word(%sa);\n", name, name); break; case sz_long: printf("\tLONG %s = get_long(%sa);\n", name, name); break; default: abort(); } break; case Ad8r: printf("\tCPTR %sa = regs.a[%s];\n", name, reg);#if 0 printf("\tUWORD %sdp = nextiword();\n", name); printf("\t%sa += (LONG)(BYTE)(%sdp & 0xFF);\n", name, name); start_brace(); printf("\tULONG %sdpr = %sdp & 0x8000 ? regs.a[(%sdp & 0x7000) >> 12] : regs.d[(%sdp & 0x7000) >> 12];\n", name, name, name, name); printf("\tif (!(%sdp & 0x800)) %sdpr = (LONG)(WORD)%sdpr;\n", name, name, name); printf("\t%sa += %sdpr;\n", name, name);#endif printf("\t%sa = get_disp_ea (%sa, nextiword());\n", name, name); if (getv) { start_brace(); switch(size) { case sz_byte: printf("\tBYTE %s = get_byte(%sa);\n", name, name); break; case sz_word: printf("\tWORD %s = get_word(%sa);\n", name, name); break; case sz_long: printf("\tLONG %s = get_long(%sa);\n", name, name); break; default: abort(); } } break; case PC16: printf("\tCPTR %sa = m68k_getpc();\n", name); printf("\t%sa += (LONG)(WORD)nextiword();\n", name); if (getv) { start_brace(); switch(size) { case sz_byte: printf("\tBYTE %s = get_byte(%sa);\n", name, name); break; case sz_word: printf("\tWORD %s = get_word(%sa);\n", name, name); break; case sz_long: printf("\tLONG %s = get_long(%sa);\n", name, name); break; default: abort(); } } break; case PC8r: printf("\tCPTR %sa = m68k_getpc();\n", name);#if 0 printf("\tUWORD %sdp = nextiword();\n", name); printf("\t%sa += (LONG)(BYTE)(%sdp & 0xFF);\n", name, name); start_brace(); printf("\tULONG %sdpr = %sdp & 0x8000 ? regs.a[(%sdp & 0x7000) >> 12] : regs.d[(%sdp & 0x7000) >> 12];\n", name, name, name, name); printf("\tif (!(%sdp & 0x800)) %sdpr = (LONG)(WORD)%sdpr;\n", name, name, name); printf("\t%sa += %sdpr;\n", name, name);#endif printf("\t%sa = get_disp_ea (%sa, nextiword());\n", name, name); if (getv) { start_brace(); switch(size) { case sz_byte: printf("\tBYTE %s = get_byte(%sa);\n", name, name); break; case sz_word: printf("\tWORD %s = get_word(%sa);\n", name, name); break; case sz_long: printf("\tLONG %s = get_long(%sa);\n", name, name); break; default: abort(); } } break; case absw: printf("\tCPTR %sa = (LONG)(WORD)nextiword();\n", name); if (getv) switch(size) { case sz_byte: printf("\tBYTE %s = get_byte(%sa);\n", name, name); break; case sz_word: printf("\tWORD %s = get_word(%sa);\n", name, name); break; case sz_long: printf("\tLONG %s = get_long(%sa);\n", name, name); break; default: abort(); } break; case absl: printf("\tCPTR %sa = nextilong();\n", name); if (getv) switch(size) { case sz_byte: printf("\tBYTE %s = get_byte(%sa);\n", name, name); break; case sz_word: printf("\tWORD %s = get_word(%sa);\n", name, name); break; case sz_long: printf("\tLONG %s = get_long(%sa);\n", name, name); break; default: abort(); } break; case imm: if (getv) switch(size) { case sz_byte: printf("\tBYTE %s = nextiword();\n", name); break; case sz_word: printf("\tWORD %s = nextiword();\n", name); break; case sz_long: printf("\tLONG %s = nextilong();\n", name); break; default: abort(); } break; case imm0: if (!getv) abort(); printf("\tBYTE %s = nextiword();\n", name); break; case imm1: if (!getv) abort(); printf("\tWORD %s = nextiword();\n", name); break; case imm2: if (!getv) abort(); printf("\tLONG %s = nextilong();\n", name); break; case immi: if (!getv) abort(); printf("\tULONG %s = %s;\n", name, reg); break; default: abort(); }}static void genastore(char *from, amodes mode, char *reg, wordsizes size, char *to){ switch(mode) { case Dreg: switch(size) { case sz_byte: printf("\tregs.d[%s] &= ~0xff; regs.d[%s] |= (%s) & 0xff;\n", reg, reg, from); break; case sz_word: printf("\tregs.d[%s] &= ~0xffff; regs.d[%s] |= (%s) & 0xffff;\n", reg, reg, from); break; case sz_long: printf("\tregs.d[%s] = (%s);\n", reg, from); break; default: abort(); } break; case Areg: switch(size) { case sz_word: printf("\tregs.a[%s] = (LONG)(WORD)(%s);\n", reg, from); break; case sz_long: printf("\tregs.a[%s] = (%s);\n", reg, from); break; default: abort(); } break; case Aind: case Aipi: case Apdi: case Ad16: case Ad8r:
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -