📄 outas386.c
字号:
/*
* 68K/386 32-bit C compiler.
*
* copyright (c) 1997, David Lindauer
*
* This compiler is intended for educational use. It may not be used
* for profit without the express written consent of the author.
*
* It may be freely redistributed, as long as this notice remains intact
* and either the original sources or derived sources
* are distributed along with any executables derived from the originals.
*
* The author is not responsible for any damages that may arise from use
* of this software, either idirect or consequential.
*
* v1.35 March 1997
* David Lindauer, gclind01@starbase.spd.louisville.edu
*
* Credits to Mathew Brandt for original K&R C compiler
*
*/
#include <stdio.h>
#include <ctype.h>
#include "expr.h"
#include "c.h"
#include "gen386.h"
#include "diag.h"
int skipsize = 0;
int addsize = 0;
typedef struct muldiv {
struct muldiv * link;
long value;
double floatvalue;
int size;
int label;
} MULDIV;
/* variable initialization */
char segregs[] = "CSDSESFSGSSS";
extern char outfile[];
extern int prm_flat;
extern SYM *currentfunc;
extern int prm_cmangle;
extern HASHREC **globalhash;
extern int phiused;
extern long nextlabel;
extern FILE *outputFile;
extern int global_flag;
enum e_gt { nogen, bytegen, wordgen, longgen, floatgen, doublegen, longdoublegen, storagegen,srrefgen };
enum e_sg { noseg, codeseg, dataseg,bssxseg,startupxseg,rundownxseg,cppxseg };
extern int prm_asmfile;
extern int prm_lines,prm_nasm;
static struct slit *strtab;
static int uses_float;
MULDIV *muldivlink = 0;
enum e_gt gentype = nogen; /* Current DC type */
enum e_sg curseg = noseg; /* Current seg */
int outcol = 0; /* Curront col (roughly) */
int newlabel;
int needpointer;
static int nosize = 0;
static int phiput;
/* List of opcodes
* This list MUST be in the same order as the op_ enums
*/
ASMNAME oplst[] = {
{ "reserved", op_reserved,0 },
{ "line#", op_reserved,0 },
{ "label", op_reserved,0 },
{ "flabel", op_reserved,0 },
{ "seq@", op_reserved,0 },
{ "db", op_reserved,0 },
{ "dd", op_reserved,0 },
{ "aaa", op_aaa,0 },
{ "aad", op_aad,0 },
{ "aam", op_aam,0 },
{ "aas", op_aas,0 },
{ "add", op_add,OPE_MATH },
{ "adc", op_adc,OPE_MATH },
{ "and", op_and,OPE_MATH },
{ "arpl", op_arpl,OPE_ARPL },
{ "bound", op_bound,OPE_BOUND },
{ "bsf", op_bsf,OPE_BITSCAN },
{ "bsr", op_bsr,OPE_BITSCAN },
{ "bswap",op_bswap,OPE_REG32 },
{ "btc", op_btc,OPE_BIT },
{ "bt", op_bt,OPE_BIT },
{ "bts", op_bts,OPE_BIT },
{ "call", op_call,OPE_CALL },
{ "cbw", op_cbw,0 },
{ "cwde", op_cwde,0 },
{ "cwd", op_cwd, 0 },
{ "cdq", op_cdq,0 },
{ "clc", op_clc,0 },
{ "cld", op_cld,0 },
{ "cli", op_cli,0 },
{ "clts", op_clts, 0 },
{ "cmc", op_cmc, 0 },
{ "cmp", op_cmp, OPE_MATH },
{ "cmps", op_cmps, OPE_CMPS },
{ "cmpsb", op_cmpsb, 0 },
{ "cmpsw", op_cmpsw, 0 },
{ "cmpsd", op_cmpsd, 0 },
{ "daa",op_daa,0 },
{ "das", op_das,0 },
{ "dec",op_dec, OPE_INCDEC},
{ "div", op_div, OPE_RM},
{ "enter", op_enter, OPE_ENTER},
{ "hlt", op_hlt, 0 },
{ "idiv", op_idiv, OPE_RM },
{ "imul", op_imul, OPE_IMUL },
{ "in", op_in, OPE_IN },
{ "inc", op_inc, OPE_INCDEC },
{ "ins", op_ins, OPE_INS },
{ "insb", op_insb, 0 },
{ "insw", op_insw, 0 },
{ "insd", op_insd, 0 },
{ "int" , op_int, OPE_IMM8 },
{ "into", op_into, 0 },
{ "invd", op_invd, 0 },
{ "iret", op_iret, 0},
{ "iretd", op_iretd, 0},
{ "ja", op_ja, OPE_RELBRA},
{ "jnbe", op_jnbe, OPE_RELBRA},
{ "jae", op_jae, OPE_RELBRA},
{ "jnb", op_jnb, OPE_RELBRA},
{ "jnc", op_jnc, OPE_RELBRA},
{ "jb", op_jb, OPE_RELBRA},
{ "jc", op_jc, OPE_RELBRA},
{ "jnae", op_jnae, OPE_RELBRA},
{ "jbe", op_jbe, OPE_RELBRA},
{ "jna", op_jna, OPE_RELBRA},
{ "jecxz", op_jecxz, OPE_RELBR8},
{ "je",op_je, OPE_RELBRA },
{ "jg",op_jg, OPE_RELBRA },
{ "jnle",op_jnle, OPE_RELBRA },
{ "jl",op_jl, OPE_RELBRA },
{ "jnge",op_jnge, OPE_RELBRA },
{ "jge", op_jge, OPE_RELBRA },
{ "jnl", op_jnl, OPE_RELBRA },
{ "jle", op_jle, OPE_RELBRA },
{ "jng", op_jng, OPE_RELBRA },
{ "jne", op_jne, OPE_RELBRA },
{ "jo", op_jo, OPE_RELBRA },
{ "jno", op_jno, OPE_RELBRA },
{ "jp", op_jp, OPE_RELBRA },
{ "jpe", op_jpe, OPE_RELBRA },
{ "jpo", op_jpo, OPE_RELBRA },
{ "js", op_js, OPE_RELBRA} ,
{ "jns", op_jns, OPE_RELBRA },
{ "jmp", op_jmp, OPE_JMP },
{ "lahf", op_lahf, 0 },
{ "lar", op_lar, OPE_REGRM },
{ "lds", op_lds, OPE_LOADSEG },
{ "les", op_les, OPE_LOADSEG },
{ "lfs", op_lfs, OPE_LOADSEG },
{ "lgs", op_lgs, OPE_LOADSEG },
{ "lss", op_lss, OPE_LOADSEG },
{ "lea", op_lea, OPE_REGRM },
{ "leave", op_leave, 0 },
{ "lgdt", op_lgdt, OPE_LGDT },
{ "lidt", op_lidt, OPE_LIDT },
{ "lldt", op_lldt, OPE_RM16 },
{ "lmsw", op_lmsw, OPE_RM16 },
{ "lock", op_lock, 0 },
{ "lods", op_lods, OPE_LODS },
{ "lodsb", op_lodsb, 0 },
{ "lodsw", op_lodsw, 0 },
{ "lodsd", op_lodsd, 0 },
{ "loop",op_loop, OPE_RELBR8 },
{ "loope",op_loope, OPE_RELBR8 },
{ "loopz",op_loopz, OPE_RELBR8 },
{ "loopne",op_loopne, OPE_RELBR8 },
{ "loopnz",op_loopnz, OPE_RELBR8 },
{ "lsl", op_lsl, OPE_REGRM },
{ "ltr", op_ltr, OPE_RM16 },
{ "mov", op_mov, OPE_MOV },
{ "movs", op_movs, OPE_MOVS },
{ "movsb", op_movsb, 0 },
{ "movsw", op_movsw, 0 },
{ "movsd", op_movsd, 0 },
{ "movsx", op_movsx, OPE_MOVSX} ,
{ "movzx", op_movzx, OPE_MOVSX} ,
{ "mul", op_mul, OPE_RM },
{ "neg", op_neg, OPE_RM },
{ "not", op_not, OPE_RM },
{ "nop", op_nop, 0 },
{ "or", op_or,OPE_MATH },
{ "out", op_out,OPE_OUT },
{ "outs", op_outs, OPE_OUTS },
{ "outsb", op_outsb, 0 },
{ "outsw", op_outsw, 0 },
{ "outsd", op_outsd, 0 },
{ "pop",op_pop, OPE_PUSHPOP },
{ "popa", op_popa, 0 },
{ "popad", op_popad, 0 },
{ "popf", op_popf, 0 },
{ "popfd", op_popfd, 0 },
{ "push",op_push, OPE_PUSHPOP },
{ "pusha", op_pusha, 0 },
{ "pushad", op_pushad, 0 },
{ "pushf", op_pushf, 0 },
{ "pushfd", op_pushfd, 0 },
{ "rcl", op_rcl, OPE_SHIFT },
{ "rcr", op_rcr, OPE_SHIFT },
{ "rol", op_rol, OPE_SHIFT },
{ "ror", op_ror, OPE_SHIFT },
{ "rep", op_rep, 0 },
{ "repne", op_repne, 0 },
{ "repe", op_repe, 0 },
{ "repnz", op_repnz, 0 },
{ "repz", op_repz, 0 },
{ "ret", op_ret, OPE_RET },
{ "sahf", op_sahf, 0 },
{ "sal", op_sal, OPE_SHIFT },
{ "sar", op_sar, OPE_SHIFT },
{ "shl", op_shl, OPE_SHIFT },
{ "shr", op_shr, OPE_SHIFT },
{ "sbb", op_sbb,OPE_MATH },
{ "scas", op_scas, OPE_SCAS },
{ "scasb", op_scasb, 0 },
{ "scasw", op_scasw, 0 },
{ "scasd", op_scasd, 0 },
{ "seta", op_seta, OPE_SET},
{ "setnbe", op_setnbe, OPE_SET},
{ "setae", op_setae, OPE_SET},
{ "setnb", op_setnb, OPE_SET},
{ "setnc", op_setnc, OPE_SET},
{ "setb", op_setb, OPE_SET},
{ "setc", op_setc, OPE_SET},
{ "setnae", op_setnae, OPE_SET},
{ "setbe", op_setbe, OPE_SET},
{ "setna", op_setna, OPE_SET},
{ "sete",op_sete, OPE_SET },
{ "setg",op_setg, OPE_SET },
{ "setnle",op_setnle, OPE_SET },
{ "setl",op_setl, OPE_SET },
{ "setnge",op_setnge, OPE_SET },
{ "setge", op_setge, OPE_SET },
{ "setnl", op_setnl, OPE_SET },
{ "setle", op_setle, OPE_SET },
{ "setng", op_setng, OPE_SET },
{ "setne", op_setne, OPE_SET },
{ "seto", op_seto, OPE_SET },
{ "setno", op_setno, OPE_SET },
{ "setp", op_setp, OPE_SET },
{ "setpe", op_setpe, OPE_SET },
{ "setpo", op_setpo, OPE_SET },
{ "sets", op_sets, OPE_SET} ,
{ "setns", op_setns, OPE_SET },
{ "sgdt", op_sgdt, OPE_LGDT },
{ "sidt", op_sidt, OPE_LIDT },
{ "sldt", op_sldt, OPE_RM16 },
{ "smsw", op_smsw, OPE_RM16 },
{ "shld", op_shld, OPE_SHLD },
{ "shrd", op_shrd, OPE_SHLD },
{ "stc", op_stc, 0 },
{ "std", op_std, 0 },
{ "sti", op_sti, 0 },
{ "stos", op_stos, OPE_STOS },
{ "stosb", op_stosb, 0 },
{ "stosw", op_stosw, 0 },
{ "stosd", op_stosd, 0 },
{ "str", op_str, OPE_RM16 },
{ "sub", op_sub, OPE_MATH },
{ "test", op_test, OPE_TEST },
{ "verr", op_verr, OPE_RM16 },
{ "verw", op_verw, OPE_RM16 },
{ "wait", op_wait, 0 },
{ "wbinvd", op_wbinvd, 0 },
{ "xchg", op_xchg, OPE_XCHG },
{ "xlat", op_xlat, OPE_XLAT },
{ "xlatb", op_xlatb, 0 },
{ "xor", op_xor,OPE_MATH },
{ "f2xm1", op_f2xm1, 0 },
{ "fabs", op_fabs, 0 },
{ "fadd", op_fadd, OPE_FMATH },
{ "faddp", op_faddp, OPE_FMATHP },
{ "fiadd", op_fiadd, OPE_FMATHI },
{ "fchs", op_fchs, 0 },
{ "fclex", op_fclex, 0 },
{ "fnclex", op_fnclex, 0 },
{ "fcom", op_fcom, OPE_FCOM },
{ "fcomp", op_fcomp, OPE_FCOM },
{ "fcompp", op_fcompp, 0 },
{ "fcos", op_fcos, 0 },
{ "fdecstp", op_fdecstp, 0 },
{ "fdiv", op_fdiv, OPE_FMATH },
{ "fdivp", op_fdivp, OPE_FMATHP },
{ "fidiv", op_fidiv, OPE_FMATHI },
{ "fdivr", op_fdivr, OPE_FMATH },
{ "fdivrp", op_fdivrp, OPE_FMATHP },
{ "fidivr", op_fidivr, OPE_FMATHI },
{ "ffree", op_ffre, OPE_FREG },
{ "ficom", op_ficom, OPE_FICOM },
{ "ficomp", op_ficomp, OPE_FICOM },
{ "fild", op_fild, OPE_FILD },
{ "fincstp", op_fincstp, 0 },
{ "finit", op_finit, 0 },
{ "fninit", op_fninit, 0 },
{ "fist", op_fist, OPE_FIST },
{ "fistp", op_fistp, OPE_FILD },
{ "fld", op_fld, OPE_FLD },
{ "fldz", op_fldz, 0},
{ "fldpi", op_fldpi, 0},
{ "fld1", op_fld1, 0},
{ "fldl2t", op_fld2t, 0},
{ "fldl2e", op_fld2e, 0},
{ "fldlg2", op_fldlg2, 0},
{ "fldln2", op_fldln2, 0},
{ "fldcw", op_fldcw, OPE_M16 },
{ "fldsw", op_fldsw, OPE_M16 },
{ "fldenv", op_fldenv, OPE_MN },
{ "fmul", op_fmul, OPE_FMATH},
{ "fmulp", op_fmulp, OPE_FMATHP},
{ "fimul", op_fimul, OPE_FMATHI },
{ "fpatan", op_fpatan, 0 },
{ "fprem", op_fprem, 0 },
{ "fprem1", op_fprem1, 0 },
{ "fptan", op_fptan, 0 },
{ "frndint", op_frndint, 0 },
{ "frstor", op_frstor, OPE_MN },
{ "fsave", op_fsave, OPE_MN },
{ "fnsave", op_fnsave, OPE_MN },
{ "fscale", op_fscale, 0 },
{ "fsin", op_fsin, 0 },
{ "fsincos", op_fsincos, 0 },
{ "fsqrt", op_fsqrt, 0 },
{ "fst", op_fst, OPE_FST},
{ "fstp", op_fstp, OPE_FSTP},
{ "fstcw", op_fstcw, OPE_M16},
{ "fstsw", op_fstsw, OPE_M16},
{ "fnstcw", op_fnstcw, OPE_M16},
{ "fnstsw", op_fnstsw, OPE_M16},
{ "fstenv", op_fstenv, OPE_MN },
{ "fnstenv", op_fsntenv, OPE_MN },
{ "fsub", op_fsub, OPE_FMATH},
{ "fsubp", op_fsubp, OPE_FMATHP},
{ "fisub", op_fisub, OPE_FMATHI},
{ "fsubr", op_fsubr, OPE_FMATH},
{ "fsubrp", op_fsubrp, OPE_FMATHP},
{ "fisubr", op_fisubr, OPE_FMATHI},
{ "ftst", op_ftst, 0},
{ "fucom", op_fucom, OPE_FUCOM },
{ "fucomp", op_fucomp, OPE_FUCOM },
{ "fucompp", op_fucompp, 0 },
{ "fwait", op_fwait, 0 },
{ "fxam", op_fxam, 0 },
{ "fxch", op_fxch, OPE_FXCH },
{ "fxtract", op_fxtract, 0 },
{ "fyl2x", op_fyl2x, 0 },
{ "fyl2xp1", op_fyl2xp1, 0 },
{0,0,0 },
};
/* Init module */
void outcodeini(void)
{
strtab = 0;
gentype = nogen;
curseg = noseg;
outcol = 0;
newlabel = FALSE;
phiput = FALSE;
}
void nl(void)
/*
* New line
*/
{ if (prm_asmfile) {
if(outcol > 0) {
fputc('\n',outputFile);
outcol = 0;
gentype = nogen;
}
if (phiused && !phiput)
fputc(0x1f,outputFile);
}
}
/* Put an opcode
*/
void outop(char *name)
{
fputc('\t',outputFile);
while (*name)
fputc(toupper(*name++),outputFile);
}
void putop(enum e_op op)
{
if (prm_nasm) {
skipsize = (op == op_lea);
addsize = (op == op_push);
if (op == op_fwait) {
/* NASM uses WAIT instead of FWAIT */
outop(oplst[op_fwait].word+1);
return;
}
}
if (op > op_fyl2xp1)
DIAG("illegal opcode.");
else
outop(oplst[op].word);
uses_float=(op >=op_f2xm1);
}
void putconst(ENODE *offset)
/*
* put a constant to the outputFile file.
*/
{ switch( offset->nodetype )
{
case en_autoreg:
case en_autocon:
case en_icon:
case en_lcon:
case en_iucon:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -