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

📄 oxccai.c

📁 OXCC is a multipass, interpreting C compiler with several language extensions. It generates an Archi
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
	oxccai.c -- v1.430 ANF to intel asmcode generator

	Copyright (c) 1995
	Norman D. Culver dba
	Oxbow Software
	1323 S.E. 17th Street #662
	Ft. Lauderdale, FL 33316
	(954) 463-4754
	ndc@icanect.net
	All rights reserved.

 * Redistribution and use in source and binary forms are permitted
 * provided that: (1) source distributions retain this entire copyright
 * notice and comment, and (2) distributions including binaries display
 * the following acknowledgement:  ``This product includes software
 * developed by Norman D. Culver dba Oxbow Software''
 * in the documentation or other materials provided with the distribution
 * and in all advertising materials mentioning features or use of this
 * software.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

*/
#define MAJOR_VERSION 1
#define MINOR_VERSION 433

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <setjmp.h>
#include <time.h>

#define SUPPORT_LONG_DOUBLE 0
#define SUPPORT_LONG_LONG 1

#define NEED_FUNCTHUNK 1
#define NEED_ANFDEFS 1
#include "oxanf.h"
	
#define PROG oxccai
#define USING_FRAMEWORK 1
#define HOST_IS_LITTLE_ENDIAN 1
#define REALLY_NEED_OFFSETS 0
#define FUNCDATA (iv->category+1)

#define VFPRINTF(a,b) vfprintf(stderr,a,b)
#define PERROR prerror
#define PWARN prwarn
#define PRINTF info
static void prerror(const char *, ...);
static void prwarn(const char *, ...);
static void info(const char *, ...);
int cfeprintf(const char *, ...);

#define FILEWRITE(buf, cnt)\
{if(!iv->errors){if(fwrite(buf, 1, cnt, iv->outfile) != cnt)iv->errors = 12;}}

#define ROUNDING(a,b) ((a+(b-1))&~(b-1))
#define ROUNDUP(a,b) a += ROUNDING(a,b)

#define KEYEQ(a,b) ((a)[0] == (b)[0] && (a)[1] == (b)[1])
#define KEYLT(a,b) (((a)[1] < (b)[1]) || ((a)[1] == (b)[1] && (a)[0] < (b)[0]))
#define MIN(a,b) (((a) < (b)) ? (a) : (b))

/* ======================== CONCATENIZATION MACROS ==================== */

#define	_cat2_(a, b)	a##b
#define _cat_(a, b)	_cat2_(a, b)
#define Global(a) _cat_(PROG, a)

#define _pname2_(x)	#x
#define _pname1_(x)	_pname2_(x)
#define pName		_pname1_(PROG)


/* ============== ENDIAN MACROS (input format is litle endian) ==== */

#if HOST_IS_LITTLE_ENDIAN
#define GL(a) a
#define GS(a) a
#define PL(a) a
#define PS(a) a
#else
#endif

/* =================== INPUT DATA FORMATS ========================== */

#define INFILE_SYMNUM 1
#define OUTFILE_SYMNUM 2

/* ====================== STRUCTURES AND TYPEDEFS ======================== */
typedef struct _jl {
	struct _jl *next;
	void *p;
	char *q;
	long *plabelval;
	long offset;
} *PJL;

typedef struct _el {
	struct _el *next;
	long spot;
	short symnum;
} *PEL;

typedef struct _afile {
	unsigned char *file_p;
	PopI header_p;
	PopI size_p;
	unsigned char *symtext_p;
	unsigned char *prog_p;
	unsigned char *data_p;
	unsigned char *switch_p;
	unsigned char *decl_p;
	unsigned char *maxtemp_p;
	unsigned char *seg_p;
	unsigned char **symaddr;
	unsigned char **decladdr;
	unsigned long thunk_offset;
	unsigned long bss_offset;
	int maxtemp;
	int maxtempclass;
	void *datatbl;
	short *symtran;
	unsigned short *decltran;
	int filenum;
	int numsyms;
	int numdecls;
	int numrelocs;
	int numsegs;
} *Pafile;

typedef struct _iv {
	int category;
	FILE *outfile;
	char *outname;
	char *infile_name;
	int remove_infile;
	int argc;
	char **argv;

	unsigned char **symaddr;
	unsigned char **decladdr;

	struct _nodeO *ob_usedhead;
	struct _nodeO *ob_usedtail;
	struct _nodeO *ob;
	unsigned char *ob_buf;
	int ob_bufcnt;
	int ob_nodecnt;
	struct _nodeO *first_ob;

	struct _nodeC *cod_usedhead;
	struct _nodeC *cod_usedtail;
	struct _nodeC *cod;
	unsigned char *cod_buf;
	int cod_nodecnt;
	int cod_bufcnt;
	struct _nodeC *first_cod;
	struct _nodeC *regcode;
	long regsave;
	long stksiz;

	int numfiles;
	int lastlabel;
	int labelnum;
	int botlabel;
	int errors;
	int numsyms;
	int numdecls;
	int numsegs;
	int maxtemp;
	int maxtempclass;
	unsigned long total_size;
	unsigned long thunk_offset;
	unsigned long bss_offset;
	long first_temp;
	long killop;
	long numnested;
	long lastline;
	void *reloctbl;
	void *newreloctbl;
	void *extrntbl;
	void *gbltbl;
	void *symtbl;
	void *labeltbl;
	void *newlabeltbl;
	void *tmptbl;
	void *segtbl;
	void *functbl;
	void *finalsymtbl;
	void *finalstringpack;
	long finalpacksize;
	void *datatbl;
	void *builtintbl;
	int in_builtin;
	int has_structret;
	int temps_written;

	PJL jbuf;
	void *jbufstart;
	int jmpcnt;
	int jbufcnt;
	long out_offset;
	long func_offset;
	int extmark;
	short markedsym[10];
	char *markedbuf[10];
	int filenum;
	Pafile files[1024];
	char debug;
	char only_debug;
	char strip;
	char listing_wanted;
	char target_assembler;
	char target_hardware;
	char target_debugger;
	char target_os;
	char memory_model;
	char obj_format;
} *Piv;

struct _gloval {
	char *symname;
	int symnum;
	unsigned char *p;
	Pafile pf;
};
struct _dkey {
	unsigned long offset;
	long pad;
};
struct _dval {
unsigned long size;
unsigned char *p;
unsigned char *prevp;
long locid;
short fileno;
};
struct _rkey {/* key area of reloctbl node */
	unsigned long spot;
	long fileno;
};
struct _rval {/* value area of reloctbl node */
	unsigned char *p;
	unsigned long base;
	long offset;
	short rsym;
	unsigned char opcode;
	char rsize;
	short fileno;
};


/* Internal User API */
static void *Cmalloc(int category, unsigned amount);
static void *Ccalloc(int category, unsigned nelems, unsigned elemsize);
static void *Crealloc(int category, void* buf, unsigned newsize);
static void Cfree(int category, void* buf);
static void Cfreecat(int category);
static int Cmemrange(int category, unsigned* minp, unsigned* maxp);
static int Cusedrange(int category, unsigned* minp, unsigned* maxp);
static void Ctotrange(unsigned* minp,unsigned* maxp);
static int Cnewcat(void);
static void Cguard(int category);
static void* NewSymTable(int category, int nbins);
static int SymFind(void *tbl, void *key, void *result);
static int SymFindRange(void *tbl, void *key, void *result);
static void *SymInsert(void *tbl, void *key, void *value, int datsiz);
static int StringInsert(void *tbl, char *string, void *result);
static int StringFind(void *tbl, char *string, void *result);
static void SymDelete(void *tbl, void *key);
static int SymHead(void *tbl);
static int SymNext(void *tbl);
static void SymGetMark(void *tbl, void *markptr);
static int SymMarkNext(void *tbl, void *mark);
static void SymSetMark(void *tbl, void *markptr);
static void SymKey(void *tbl, void *keyptr);
static void SymValue(void *tbl, void *datptr);
static void *seg_find(Piv iv, int id);
static char *filenameof(char *path);
static char *propernameof(Piv iv, char *name);

/* END: User API */

/* ====================== PUT UNIQUE CODE HERE ========================= */
static void *do_stmt(Piv iv, unsigned char *p);
static void *do_expr(Piv iv, unsigned char *p);
static void do_bracket(Piv iv, unsigned char *p, unsigned char *q);
static void *do_something(Piv iv, unsigned char *p);
extern char *ctime();

/* ===================== ASMCODE OUTPUT GENERATOR ======================= */
#define DUMP(args...) fprintf(((Piv)iv)->outfile, ## args)
#define QDUMP(arg) fputs(arg, ((Piv)iv)->outfile)
#define QDUMPC(arg) fputc(arg, ((Piv)iv)->outfile)

#define SOURCE 0
#define DESTINATION 1
#define USE_ADDR (0x0001)
#define NEEDS_CONVERSION (0x0002)

#define BWORD (1)
#define SWORD (2)
#define LWORD (3)

#define INDIRECT (0x01)
#define INDEXED (0x02)

/* WARNING ONLY GCC WILL COMPILE THIS */
#define ENCODE(args...) \
{iv->cod->ee = (struct _nodeE){## args}; link_cod(iv);}

typedef struct _nodeE
{
	unsigned short inst;
	unsigned char size;
	unsigned char s1;
	unsigned char s1m;
	unsigned char s2;
	unsigned char s2m;
	unsigned char d1;
	unsigned char d1m;
	unsigned char d2;
	unsigned char d2m;
	unsigned char cdat;
	long dat;
	void *ptr;
} NODEE, *PNODEE;

typedef struct _nodeC
{
	struct _nodeC *next;
	struct _nodeE ee;
} NODEC, *PNODEC;

typedef struct _nodeO 
{
	struct _nodeO *next;
	unsigned char *p;
	ND d;
	ND l;
	ND r;
	PNODEC startinst;
	PNODEC endinst;
} NODEO, *PNODEO;

static char *notice = 
	"  Generated by Oxbow Software Asmcode Backend `oxccai' version %d.%d\n\n";

static char *opnames[] = {"",
  "aaa","aad","aam","aas","adc","add","and","arpl",
  "bound","bsf","bsr","bswap","bt","btc","btr","bts",
  "call","cbw","cdq","clc","cld","cli","clts",
  "cmc","cmp","cmps","cmpxchg","cwd","cwde",
  "daa","das","dec","div",
  "enter","esc",
  "hlt",
  "idiv","imul","in","inc","ins",
  "int","into","invd","invlpg","iret","iretd","iretdf","iretf",
  "ja","jae","jb","jbe","jc","jcxz","je","jecxz","jg","jge","jl","jle","jmp",
  "jna","jnae","jnb","jnbe","jnc","jne","jng","jnge","jnl","jnle","jno","jnp",
  "jns","jnz","jo","jp","jpe","jpo","js","jz",
  "lar","lds","lea","leave","les","lfs",
  "lgdt","lgs","lidt","lldt","lmsw","lock",
  "lods","loop","loope","loopne","loopnz","loopz",
  "lsl","lss","ltr",
  "mov","movs","movsx","movzx","mul",
  "neg","nop","not",
  "or","out","outs",
  "pop","popa","popf","push","pusha","pushf",
  "rcl","rcr","ret","retf","retn","rol","ror",
  "rep","repe","repne","repnz","repz",
  "sahf","sal","sar","sbb","scas","shl","shr",
  "seta","setae","setb","setbe","setc","sete","setg","setge","setl","setle",
  "setna","setnae","setnb","setnbe","setnc","setne","setng","setnge","setnl",
  "setnle","setno","setnp","setns","setnz","seto","setp","setpe","setpo",
  "sets","setz","sgdt","sidt","sldt","smsw",
  "stc","std","sti","stos","str","sub",
  "test",
  "verr","verw",
  "wait","wbinvd",
  "xadd","xchg","xlat","xlatb","xor",

  "fabs","fadd","faddp","fbld","fbstp","fchs","fclex",
  "fcom","fcomp","fcompp","fcos",
  "fdecstp","fdisi",
  "fdiv","fdivp","fdivr","fdivrp","feni","ffree","fiadd",
  "ficom","ficomp","fidiv","fidivr","fild","fimul","fincstp","finit",
  "fist","fistp","fisub","fisubr",
  "fld","fld1","fldcw","fldenv","fldlg2","fldln2","fldl2e","fldl2t","fldpi","fldz",
  "fmul","fmulp",
  "fnclex","fndisi","fneni","fninit","fnop","fnsave","fnstcw","fnstenv","fnsts",
  "fpatan","fprem","fprem1","fptan","frndint","frstor","fsave",
  "fscale","fsin","fsincos","fsqrt","fst","fstcw","fstenv",
  "fstp",
  "fstsw","fsub","fsubr",
  "ftst","fucom","fucomp","fucompp","fwait","fxam","fxch","fxtract",
  "fyl2x","fyl2xpi","f2xmi"
};
enum  {		
  aaa=1,aad,aam,aas,adc,add,and,arpl,
  bound,bsf,bsr,bswap,bt,btc,btr,bts,
  call,cbw,cdq,clc,cld,cli,clts,
  cmc,cmp,cmps,cmpxchg,cwd,cwde,
  daa,das,dec,DIV,
  enter,esc,
  hlt,
  idiv,imul,in,inc,ins,
  INT,into,invd,invlpg,iret,iretd,iretdf,iretf,
  ja,jae,jb,jbe,jc,jcxz,je,jecxz,jg,jge,jl,jle,jmp,
  jna,jnae,jnb,jnbe,jnc,jne,jng,jnge,jnl,jnle,jno,jnp,
  jns,jnz,jo,jp,jpe,jpo,js,jz,
  lar,lds,lea,leave,les,lfs,
  lgdt,lgs,lidt,lldt,lmsw,lock,
  lods,loop,loope,loopne,loopnz,loopz,
  lsl,lss,ltr,
  mov,movs,movsx,movzx,mul,
  neg,nop,not,
  or,out,outs,
  pop,popa,popf,push,pusha,pushf,
  rcl,rcr,ret,retf,retn,rol,ror,
  rep,repe,repne,repnz,repz,
  sahf,sal,sar,sbb,scas,shl,shr,
  seta,setae,setb,setbe,setc,sete,setg,setge,setl,setle,
  setna,setnae,setnb,setnbe,setnc,setne,setng,setnge,setnl,
  setnle,setno,setnp,setns,setnz,seto,setp,setpe,setpo,
  sets,setz,sgdt,sidt,sldt,smsw,
  stc,std,sti,stos,str,sub,
  test,
  verr,verw,
  WAIT,wbinvd,
  xadd,xchg,xlat,xlatb,xor,

  fabs,fadd,faddp,fbld,fbstp,fchs,fclex,
  fcom,fcomp,fcompp,fcos,
  fdecstp,fdisi,
  fdiv,fdivp,fdivr,fdivrp,feni,ffree,fiadd,
  ficom,ficomp,fidiv,fidivr,fild,fimul,fincstp,finit,
  fist,fistp,fisub,fisubr,
  fld,fld1,fldcw,fldenv,fldlg2,fldln2,fldl2e,fldl2t,fldpi,fldz,
  fmul,fmulp,
  fnclex,fndisi,fneni,fninit,fnop,fnsave,fnstcw,fnstenv,fnsts,
  fpatan,fprem,fprem1,fptan,frndint,frstor,fsave,
  fscale,fsin,fsincos,fsqrt,fst,fstcw,fstenv,
  fstp,
  fstsw,fsub,fsubr,
  ftst,fucom,fucomp,fucompp,fwait,fxam,fxch,fxtract,
  fyl2x,fyl2xpi,f2xmi,
  ENDCODES,
  ALIGN,PUSHREGS,POPREGS,LABEL,LINE,FUNCNAME,LINEFEED
};
static char *udatnames[] = {"",
"%al","%ah","%ax","%eax","%bl","%bh","%bx","%ebx","%cl","%ch","%cx","%ecx",
"%dl","%dh","%dx","%edx","%sp","%esp","%bp","%ebp",
"%si","%esi","%di","%edi","%ss","%ds","%es","%fs","%gs","","",""
};
static char *datnames[] = {"",
"al","ah","ax","eax","bl","bh","bx","ebx","cl","ch","cx","ecx",
"dl","dh","dx","edx","sp","esp","bp","ebp",
"si","esi","di","edi","ss","ds","es","fs","gs","","",""
};
enum {
AL=1,AH,AX,EAX,BL,BH,BX,EBX,CL,CH,CX,ECX,DL,DH,DX,EDX,SP,ESP,BP,EBP,
SI,ESI,DI,EDI,SS,DS,ES,FS,GS,CONST,VARNAME,LOCATION
};

static char uwordsize[] = {' ','b','w','l'};
static char dwordsize[] = {' ','b','w','d'};

static long
symnumof(Piv iv, char *symb)
{
struct _gloval *valp;

	if(StringFind(iv->gbltbl, symb, &valp))
		return (long)valp->pf->symtran[valp->symnum];
	return 0;

}
static void
buildin(Piv iv, char *symb, unsigned char code)
{
long key[2];

	if((key[0] = symnumof(iv, symb)))
	{
		key[1] = 0;
		SymInsert(iv->builtintbl, key, &code, 1);
	}
}


static void
install_builtins(Piv iv)
{/* USE THIS TO INSTALL WHATEVER BUILTINS ARE IN THE TARGET INTERPRETER */
#define BUILDIN(a,b) buildin(iv,#a,b)

	iv->builtintbl = NewSymTable(iv->category, 191);

	BUILDIN(alloca,0);

#undef BUILDIN
}
static long
final_strofs(Piv iv, char *string)
{
long *result;

	if(StringFind(iv->finalsymtbl, string, &result))
		return result[2];	
	return 0;
}
static short
final_symnum(Piv iv, short symnum)
{
long *result;

	if(StringFind(iv->finalsymtbl, iv->symaddr[symnum], &result))
		return result[1]-1;
	return 0;
}
static void
make_final_symtab(Piv iv)
{
int i;
	iv->finalsymtbl = NewSymTable(iv->category, 0);
	if(SymHead(iv->gbltbl))
	{
		i = 0;
		while(SymNext(iv->gbltbl))
		{
		long *result;
		struct _gloval *valp;

			SymValue(iv->gbltbl, &valp);
			if(*(valp->p))
			{
				if(!StringInsert(iv->finalsymtbl, valp->symname, &result))
				{/* New Entry */
					result[1] = ++i;
				}
			}
		}
	}
}
static void *
new_nodeO(Piv iv)
{
PNODEO p;

	if(iv->ob_bufcnt < sizeof(NODEO))
	{/* Allocate a new chunk of linked list space */
	  iv->ob_bufcnt = 4080;
	  iv->ob_buf = Ccalloc(FUNCDATA, 1, iv->ob_bufcnt);
	}
	p = (PNODEO)iv->ob_buf;
	iv->ob_buf += sizeof(NODEO);
	iv->ob_bufcnt -= sizeof(NODEO);
	++iv->ob_nodecnt;
	return p;	
}
static void
link_ob(Piv iv)
{/* Attach to the used list */

	if(!iv->ob_usedhead)
	{
		iv->ob_usedhead = iv->ob;
		iv->ob_usedtail = iv->ob;
	}
	else
	{
		iv->ob_usedtail->next = iv->ob;
		iv->ob_usedtail = iv->ob;
	}
	iv->ob = new_nodeO(iv);
}
static void *
new_nodeC(Piv iv)
{
PNODEC p;

	if(iv->cod_bufcnt < sizeof(NODEC))
	{/* Allocate a new chunk of linked list space */
	  iv->cod_bufcnt = 4080;
	  iv->cod_buf = Ccalloc(FUNCDATA, 1, iv->cod_bufcnt);
	}
	p = (PNODEC)iv->cod_buf;
	iv->cod_buf += sizeof(NODEC);
	iv->cod_bufcnt -= sizeof(NODEC);
	++iv->cod_nodecnt;
	return p;	
}
static void
link_cod(Piv iv)
{/* Attach to the used list */

	if(!iv->cod_usedhead)
	{
		iv->cod_usedhead = iv->cod;
		iv->cod_usedtail = iv->cod;
	}
	else
	{
		iv->cod_usedtail->next = iv->cod;
		iv->cod_usedtail = iv->cod;
	}
	iv->cod = new_nodeC(iv);
}
static PNODEC
gen_inst(Piv iv, PNODEO pnode)
{
unsigned char opcode;
unsigned char *p;
PND d,l,r;

		d = &pnode->d;
		l = &pnode->l;
		r = &pnode->r;
		p = pnode->p;
		opcode = *p;

		switch(opcode)
		{
			/* 0 ADDRESS MODE */
			case regainop:
			case grabop:
				break;
			case retvoidop:
				ENCODE(jmp, LWORD, s1: LOCATION, dat: iv->botlabel);
				break;

⌨️ 快捷键说明

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