📄 outx86_g.c
字号:
/* * 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_SUN#define TARGET_GAS#endif#ifdef TARGET_GAS#define OUT_MODULE#include "chdr.h"#include "expr.h"#include "cglbdec.h"#include "proto.h"#include "genx86.h"#include "outproto.h"#include "version.h"/********************************************************** Type Definitions */enum e_gt{ bytegen, wordgen, longlonggen, longgen, nogen};enum e_sg{ noseg, codeseg, dataseg};/*********************************************** Static Function Definitions */static void putop P_ ((OPCODE));static void putconst P_ ((const EXPR *));static void putlen P_ ((ILEN));static void putamode P_ ((const ADDRESS *, ILEN));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_reference P_ ((SYM *));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));/********************************************************** Static Variables */static enum e_gt gentype = nogen;static enum e_sg curseg = noseg;static int outcol = 0;static SIZE align_type = 0L;#ifdef TARGET_SUNstatic const char *prefix = ".L";#elsestatic const char *prefix = "L";#endif /* TARGET_SUN */static const char *comment = "#";static const char *opl[] = { "movsbl", /* op_movsbl */ "movzbl", /* op_movzbl */ "movswl", /* op_movswl */ "movzwl", /* op_movzwl */ "movsbw", /* op_movsbw */ "movzbw", /* op_movzbw */ "cltd", /* op_cdq */ "cwtl", /* op_cwd */ "cbtw", /* op_cbw */ "mov", /* op_mov */ "xchg", /* op_xchg */ "lea", /* op_lea */ "not", /* op_not */ "neg", /* op_neg */ "add", /* op_add */ "sub", /* op_sub */ "adc", /* op_adc */ "sbb", /* op_sbb */ "imul", /* op_imul */ "idiv", /* op_idiv */ "div", /* op_div */ "and", /* op_and */ "or", /* op_or */ "xor", /* op_xor */ "inc", /* op_inc */ "dec", /* op_dec */ "cmp", /* op_cmp */ "push", /* op_push */ "pop", /* op_pop */ "jmp", /* op_jmp */ "loop", /* op_loop */ "call", /* op_call */ "leave", /* op_leave */ "enter", /* op_enter */ "ret", /* op_ret */ "test", /* op_test */ "jmp", /* op_bra */ "je", /* op_je */ "jne", /* op_jne */ "jl", /* op_jl */ "jle", /* op_jle */ "jg", /* op_jg */ "jge", /* op_jge */ "ja", /* op_ja */ "jae", /* op_jae */ "jb", /* op_jb */ "jbe", /* op_jbe */ "rep", /* op_rep */#ifdef TARGET_SUN "smov", /* op_smov */#else "movs", /* op_smov */#endif "shl", /* op_shl */ "shr", /* op_shr */ "sal", /* op_asl */ "sar", /* op_asr */ "rol", /* op_rol */ "ror", /* op_ror */ "sahf", /* op_sahf */ "sete", /* op_sete */ "setne", /* op_setne */ "setb", /* op_setb */ "setbe", /* op_setbe */ "seta", /* op_seta */ "setae", /* op_setae */ "setl", /* op_setl */ "setle", /* op_setle */ "setg", /* op_setg */ "setge", /* op_setge */ "nop", /* op_nop */#ifdef FLOAT_IEEE "fadd", /* op_fadd */ "faddp", /* op_faddp */ "fsub", /* op_fsub */ "fsubp", /* op_fsubp */ "fdiv", /* op_fdiv */ "fdivp", /* op_fdivp */ "fmul", /* op_fmul */ "fmulp", /* op_fmulp */ "fsubr", /* op_fsubr */ "fsubrp", /* op_fsubrp */ "fdivr", /* op_fdivr */ "fdivrp", /* op_fdivrp */ "fld", /* op_fld */ "fldz", /* op_fldz */ "fst", /* op_fst */ "fstp", /* op_fstp */ "fstp %st(0)", /* op_fpop */ "fild", /* op_fild */ "fildl", /* op_fildl */ "fistp", /* op_fistp */ "fistpl", /* op_fistpl */ "ftst", /* op_ftst */ "fchs", /* op_fchs */ "fcomp", /* op_fcomp */ "fcompp", /* op_fcompp */ "fnstsw", /* op_fnstsw */ "fwait", /* op_fwait */#endif /* FLOAT_IEEE */#ifdef ASM "", /* op_asm */#endif /* ASM */ ".stabd\t68,0,", /* op_line */ (char *) NULL, /* op_label */};/*****************************************************************************/static void putop P1 (OPCODE, op){ if (op >= OP_MIN && op <= OP_MAX && opl[op] != (char *) 0) { oprintf ("\t%s", opl[op]); return; } FATAL ((__FILE__, "putop", "Illegal opcode %d", op));}/* * 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 ("%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 ep %d", ep->nodetype)); break; }}/* * append the length field to an instruction. */static void putlen P1 (ILEN, l){ switch (l) { case IL0: break; case IL1: oprintf ("b"); break; case IL2: oprintf ("w"); break; case IL4: oprintf ("l"); break; case IL4 + 1: /*lint !e408*/ /* type mismatch with switch expression */ /* special value for single precision float */ oprintf ("s"); break; case IL8 + 1: /*lint !e408*/ /* type mismatch with switch expression */ /* special value for double precision float */ oprintf ("l"); break; case IL10 + 1: /*lint !e408*/ /* type mismatch with switch expression */ break; default: FATAL ((__FILE__, "putlen", "illegal length field %d", (int) l)); break; }}/* * output a general addressing mode. */static void putamode P2 (const ADDRESS *, ap, ILEN, len){ 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; switch (ap->mode) { case am_immed: oprintf ("$"); /*lint -fallthrough */ case am_direct: putconst (ap->u.offset); break; case am_dreg: case am_areg: reg = ap->preg; switch (len) { case IL1: reg = (REG) REG8 (reg); break; case IL2: reg = (REG) REG16 (reg); break; default: break; } oprintf ("%%%s", regname[reg]); break; case am_indx: if (ap->u.offset != NIL_EXPR) { putconst (ap->u.offset); } /*lint -fallthrough */ case am_ind: oprintf ("(%%%s)", regname[small_option ? REG16 (ap->preg) : ap->preg]); break; case am_indx2: if (ap->u.offset != NIL_EXPR) { putconst (ap->u.offset); } oprintf ("(%%%s,%%%s)", regname[small_option ? REG16 (ap->preg) : ap->preg], regname[small_option ? REG16 (ap->sreg) : ap->sreg]); break; case am_freg: oprintf ("%%%s", regname[ap->preg]); break; case am_line: case am_str: putconst (ap->u.offset); break; default: FATAL ((__FILE__, "putamode", "illegal address mode %d", ap->mode)); break; }}/* * output a generic instruction.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -