outx86_b.c
来自「一款拥有一定历史的C语言编译器」· C语言 代码 · 共 1,018 行 · 第 1/2 页
C
1,018 行
/* * C compiler * ========== * * Copyright 1989, 1990, 1991 Christoph van Wuellen. * Credits to Matthew Brandt. * All commercial rights reserved. * * This compiler may be redistributed as long there is no * commercial interest. The compiler must not be redistributed * without its full sources. This notice must stay intact. * * History: * * 1989 starting an 68000 C compiler, starting with material * originally by M. Brandt * 1990 68000 C compiler further bug fixes * started i386 port (December) * 1991 i386 port finished (January) * further corrections in the front end and in the 68000 * code generator. * The next port will be a SPARC port *//*****************************************************************************/#include "config.h"#ifdef INTEL#ifdef TARGET_BAS#define OUT_MODULE#include "chdr.h"#include "expr.h"#include "cglbdec.h"#include "proto.h"#include "genx86.h"#include "outproto.h"#include "version.h"/********************************************************* Macro Definitions */#define BI 1U#define SPN 2U#define FP 4U/********************************************************** Type Definitions */enum e_gt{ bytegen, wordgen, longgen, longlonggen, stringgen, nogen};enum e_sg{ noseg, codeseg, dataseg};/*********************************************** Static Function Definitions */static unsigned int putop P_ ((OPCODE));static void putconst P_ ((const EXPR *));static void putamode P_ ((const ADDRESS *, ILEN, unsigned int));static void put_header P_ ((enum e_gt, SIZE));static void seg P_ ((enum e_sg, const char *, SIZE));static void put_bseg P_ ((SIZE));static void nl P_ ((void));static void put_align P_ ((SIZE));/*********************************************** Global Function Definitions */PRIVATE void put_label P_ ((LABEL));PRIVATE void put_byte P_ ((UVAL));PRIVATE void put_dword P_ ((UVAL));PRIVATE void put_cseg P_ ((SIZE));PRIVATE void put_dseg P_ ((SIZE));PRIVATE void put_kseg P_ ((SIZE));PRIVATE void put_rseg P_ ((SIZE));PRIVATE void put_finish P_ ((void));PRIVATE void put_start P_ ((void));PRIVATE void put_reference P_ ((SYM *));/********************************************************** Static Variables */static enum e_gt gentype = nogen;static enum e_sg curseg = noseg;static int outcol = 0;static SIZE align_type = 0L;static const char *prefix = "L";static const char *comment = "|";static struct oplst{ const char *s; unsigned int sa; /* special addressing modes: * BI immediate is bracketed, * SPN size prefix needed. * FP 387 op */} opl[] ={ { "movsx", BI | SPN} , /* op_movsbl */ { "movzx", BI | SPN} , /* op_movzbl */ { "movsx", BI | SPN} , /* op_movswl */ { "movzx", BI | SPN} , /* op_movzwl */ { "movsx", BI | SPN} , /* op_movsbw */ { "movzx", BI | SPN} , /* op_movzbw */ { "cdq", BI | SPN} , /* op_cdq */ { "cwd", BI | SPN} , /* op_cwd */ { "cbw", BI | SPN} , /* op_cbw */ { "mov", BI | SPN} , /* op_mov */ { "xchg", BI | SPN} , /* op_xchg */ { "lea", BI | SPN} , /* op_lea */ { "not", BI | SPN} , /* op_not */ { "neg", BI | SPN} , /* op_neg */ { "add", BI | SPN} , /* op_add */ { "sub", BI | SPN} , /* op_sub */ { "adc", BI | SPN} , /* op_adc */ { "sbb", BI | SPN} , /* op_sbb */ { "imul", BI | SPN} , /* op_imul */ { "idiv", BI | SPN} , /* op_idiv */ { "div", BI | SPN} , /* op_div */ { "and", BI | SPN} , /* op_and */ { "or", BI | SPN} , /* op_or */ { "xor", BI | SPN} , /* op_xor */ { "inc", BI | SPN} , /* op_inc */ { "dec", BI | SPN} , /* op_dec */ { "cmp", BI | SPN} , /* op_cmp */ { "push", BI | SPN} , /* op_push */ { "pop", BI | SPN} , /* op_pop */ { "jmp", SPN} , /* op_jmp */ { "loop", SPN} , /* op_loop */ { "call", SPN} , /* op_call */ { "leave", SPN} , /* op_leave */ { "enter", SPN} , /* op_enter */ { "ret", SPN} , /* op_ret */ { "test", BI | SPN} , /* op_test */ { "jmp", SPN} , /* op_bra */ { "je", SPN} , /* op_je */ { "jne", SPN} , /* op_jne */ { "jl", SPN} , /* op_jl */ { "jle", SPN} , /* op_jle */ { "jg", SPN} , /* op_jg */ { "jge", SPN} , /* op_jge */ { "ja", SPN} , /* op_ja */ { "jae", SPN} , /* op_jae */ { "jb", SPN} , /* op_jb */ { "jbe", SPN} , /* op_jbe */ { "rep", SPN} , /* op_rep */ { "movs", BI | SPN} , /* op_smov */ { "shl", BI | SPN} , /* op_shl */ { "shr", BI | SPN} , /* op_shr */ { "sal", BI | SPN} , /* op_asl */ { "sar", BI | SPN} , /* op_asr */ { "rol", BI | SPN} , /* op_rol */ { "ror", BI | SPN} , /* op_ror */ { "sahf", BI | SPN} , /* op_sahf */ { "sete", SPN} , /* op_sete */ { "setne", SPN} , /* op_setne */ { "setb", SPN} , /* op_setb */ { "setbe", SPN} , /* op_setbe */ { "seta", SPN} , /* op_seta */ { "setae", SPN} , /* op_setae */ { "setl", SPN} , /* op_setl */ { "setle", SPN} , /* op_setle */ { "setg", SPN} , /* op_setg */ { "setge", SPN} , /* op_setge */ { "nop", 0} , /* op_nop */#ifdef FLOAT_IEEE { "fadd", BI | SPN | FP} , /* op_fadd */ { "faddp", BI | SPN | FP} , /* op_faddp */ { "fsub", BI | SPN | FP} , /* op_fsub */ { "fsubp", BI | SPN | FP} , /* op_fsubp */ { "fdiv", BI | SPN | FP} , /* op_fdiv */ { "fdivp", BI | SPN | FP} , /* op_fdivp */ { "fmul", BI | SPN | FP} , /* op_fmul */ { "fmulp", BI | SPN | FP} , /* op_fmulp */ { "fsubr", BI | SPN | FP} , /* op_fsubr */ { "fsubrp", BI | SPN | FP} , /* op_fsubrp */ { "fdivr", BI | SPN | FP} , /* op_fdivr */ { "fdivrp", BI | SPN | FP} , /* op_fdivrp */ { "fld", BI | SPN | FP} , /* op_fld */ { "fldz", BI | SPN | FP} , /* op_fldz */ { "fst", BI | SPN | FP} , /* op_fst */ { "fstp", BI | SPN | FP} , /* op_fstp */ { "fstp st(0)", BI | SPN | FP} , /* op_fpop */ { "fild", BI | SPN | FP} , /* op_fild */ { "fildl", BI | SPN | FP} , /* op_fildl */ { "fistp", BI | SPN | FP} , /* op_fistp */ { "fistpl", BI | SPN | FP} , /* op_fistpl */ { "ftst", BI | SPN | FP} , /* op_ftst */ { "fchs", BI | SPN | FP} , /* op_fchs */ { "fcomp", BI | SPN | FP} , /* op_fcomp */ { "fcompp", BI | SPN | FP} , /* op_fcompp */ { "fnstsw", BI | SPN | FP} , /* op_fnstsw */ { "fwait", BI | SPN | FP} , /* op_fwait */#endif /* FLOAT_IEEE */#ifdef ASM { "", 0} , /* op_asm */#endif /* ASM */ { "|.line", 0} , /* op_line */ { (char *) NULL, 0} /* op_label */};/*****************************************************************************/static unsigned int putop P1 (OPCODE, op){ if (op >= OP_MIN && op <= OP_MAX && opl[op].s != (char *) 0) { oprintf ("\t%s", opl[op].s); return opl[op].sa; } FATAL ((__FILE__, "putop", "illegal opcode %d", op)); return 0U; /*lint !e527 */ /* unreachable */}/* * put a constant to the output file. */static void putconst P1 (const EXPR *, ep){ if (ep == NIL_EXPR) { FATAL ((__FILE__, "putconst", "ep == 0")); } switch (ep->nodetype) { case en_autocon: case en_icon: oprintf (ep->v.i >= 0L ? "%ld" : "(%ld)", ep->v.i); break; case en_labcon: oprintf ("%s%u", prefix, (unsigned) ep->v.l); break; case en_nacon: oprintf ("%s", outlate (ep->v.str)); break; case en_sym: oprintf ("%s", outlate (nameof (ep->v.sp))); break; case en_add: putconst (ep->v.p[0]); oprintf ("+"); putconst (ep->v.p[1]); break; case en_sub: putconst (ep->v.p[0]); oprintf ("-"); putconst (ep->v.p[1]); break; case en_uminus: oprintf ("-"); putconst (ep->v.p[0]); break; case en_cast: putconst (ep->v.p[0]); break; case en_str: oprintf ("%s", ep->v.str); break; default: FATAL ( (__FILE__, "putconst", "illegal constant node %d", ep->nodetype)); break; }}/* * output a general addressing mode. */static void putamode P3 (const ADDRESS *, ap, ILEN, len, unsigned int, sa){ static const char *regname[NUMREG + 1] = { "eax", /* EAX */ "edx", /* EDX */ "ecx", /* ECX */ "ebx", /* EBX */ "esi", /* ESI */ "edi", /* EDI */ "esp", /* ESP */ "ebp", /* EBP */ "ax", /* AX */ "dx", /* DX */ "cx", /* CX */ "bx", /* BX */ "si", /* SI */ "di", /* DI */ "sp", /* SP */ "bp", /* BP */ "al", /* AL */ "dl", /* DL */ "cl", /* CL */ "bl", /* BL */ "st", /* ST(0) */ "st(1)", /* ST(1) */ "INVALID_REGISTER", "INVALID_REGISTER", }; REG reg; if (sa & SPN) { switch (len) { /* kludge for movsx and movzx */ case IL1: oprintf (" byte "); break; case IL2: oprintf (" word "); break; case IL4: oprintf (" dword "); break; case IL8: oprintf (" qword "); break; default: break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?