forked from KolibriOS/kolibrios
initial import of metcc project
git-svn-id: svn://kolibrios.org@145 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
7df9c18621
commit
51d395d0cc
118
programs/develop/metcc/trunk/libc/compile.js
Normal file
118
programs/develop/metcc/trunk/libc/compile.js
Normal file
@ -0,0 +1,118 @@
|
||||
var fso=new ActiveXObject("Scripting.FileSystemObject");
|
||||
var wsh=WScript.CreateObject("WScript.Shell");
|
||||
var curpath=".";
|
||||
var gccpath="c:\\program files\\MinGW\\MinGW\\bin\\";
|
||||
//var gccpath="cmd.exe /c ";
|
||||
var gccexe="\""+gccpath+"cc1.exe"+"\" ";
|
||||
var asexe="\""+gccpath+"as.exe"+"\" ";
|
||||
var objcopyexe="\""+gccpath+"objcopy.exe"+"\" ";
|
||||
//var gccexe=gccpath+"cc1.exe" ;
|
||||
//var asexe=gccpath+"as.exe";
|
||||
var scriptline="CREATE melibc.a\r\n";
|
||||
|
||||
curpath=".\\string\\";
|
||||
compileasm("memmove");
|
||||
compileasm("memset");
|
||||
curpath=".\\mesys\\";
|
||||
compileasm("backgr");
|
||||
compileasm("button");
|
||||
compileasm("clock");
|
||||
compileasm("date");
|
||||
compileasm("debug_board");
|
||||
compileasm("delay");
|
||||
compileasm("dga");
|
||||
compileasm("draw_bar");
|
||||
compileasm("draw_image");
|
||||
compileasm("draw_window");
|
||||
compileasm("event");
|
||||
compileasm("exit");
|
||||
compileasm("file_58");
|
||||
compileasm("ipc");
|
||||
compileasm("irq");
|
||||
compileasm("keyboard");
|
||||
compileasm("line");
|
||||
compileasm("midi");
|
||||
compileasm("pci");
|
||||
compileasm("pixel");
|
||||
compileasm("process");
|
||||
compileasm("screen");
|
||||
compileasm("sound");
|
||||
compileasm("thread");
|
||||
compileasm("window_redraw");
|
||||
compileasm("write_text");
|
||||
curpath=".\\mem\\";
|
||||
compileasm("memalloc");
|
||||
curpath=".\\mesys\\";
|
||||
compilec("debug_board_");
|
||||
curpath=".\\string\\";
|
||||
compilec("memchr");
|
||||
compilec("memcmp");
|
||||
compilec("strcat");
|
||||
compilec("strchr");
|
||||
compilec("strcmp");
|
||||
compilec("strcoll");
|
||||
compilec("strcpy");
|
||||
compilec("strcspn");
|
||||
compilec("strdup");
|
||||
compilec("strerror");
|
||||
compilec("strlen");
|
||||
compilec("strnbrk");
|
||||
compilec("strncat");
|
||||
compilec("strncmp");
|
||||
compilec("strncpy");
|
||||
compilec("strrchr");
|
||||
compilec("strspn");
|
||||
compilec("strstr");
|
||||
compilec("strtok");
|
||||
compilec("strxfrm");
|
||||
curpath=".\\file\\";
|
||||
compilec("fclose");
|
||||
compilec("fopen");
|
||||
compilec("feof");
|
||||
compilec("fflush");
|
||||
compilec("fgetc");
|
||||
compilec("fgetpos");
|
||||
compilec("fsetpos");
|
||||
compilec("fputc");
|
||||
compilec("fread");
|
||||
compilec("fwrite");
|
||||
compilec("fseek");
|
||||
compilec("ftell");
|
||||
compilec("rewind");
|
||||
compilec("fprintf");
|
||||
compilec("fscanf");
|
||||
compilec("ungetc");
|
||||
curpath=".\\start\\";
|
||||
compileasm("start");
|
||||
//linking
|
||||
scriptline+="SAVE\r\n";
|
||||
linko();
|
||||
function compileasm(filename)
|
||||
{
|
||||
wsh.Run("fasm.exe "+quote(curpath+filename+".asm")+
|
||||
" "+quote(curpath+filename+".o"),0,true);
|
||||
addo(filename);
|
||||
}
|
||||
function compilec(filename)
|
||||
{
|
||||
wsh.Run(gccexe+"-nostdinc -I .\\include -DGNUC " + quote(curpath + filename + ".c")+
|
||||
" -o " + quote(curpath + filename + ".s"),0,true);
|
||||
wsh.Run(asexe+quote(curpath+filename+".s")+" -o "+quote(curpath+filename+".o"),0,true);
|
||||
wsh.Run(objcopyexe+" -O elf32-i386 --remove-leading-char "+quote(curpath+filename+".o"),0,true);
|
||||
addo(filename);
|
||||
}
|
||||
function addo(filename)
|
||||
{
|
||||
scriptline+="ADDMOD "+curpath+filename+".o\r\n";
|
||||
}
|
||||
function linko()
|
||||
{
|
||||
//fso.DeleteFile(".\\melibc.a");
|
||||
var file=fso.OpenTextFile("./script.txt",2,true);
|
||||
file.Write(scriptline);
|
||||
wsh.Run("cmd.exe /c ar.exe -M < ./script.txt",4,true);
|
||||
}
|
||||
function quote(name)
|
||||
{
|
||||
return "\""+name+"\"";
|
||||
}
|
10
programs/develop/metcc/trunk/libc/file/fclose.c
Normal file
10
programs/develop/metcc/trunk/libc/file/fclose.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
int fclose(FILE* file)
|
||||
{
|
||||
int res;
|
||||
res=_msys_write_file(file->filename,file->filesize,file->buffer);
|
||||
free(file->buffer);
|
||||
free(file);
|
||||
return res;
|
||||
}
|
5
programs/develop/metcc/trunk/libc/file/feof.c
Normal file
5
programs/develop/metcc/trunk/libc/file/feof.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include "stdio.h"
|
||||
int feof(FILE* file)
|
||||
{
|
||||
return file->filepos>=file->filesize;
|
||||
}
|
7
programs/develop/metcc/trunk/libc/file/fflush.c
Normal file
7
programs/develop/metcc/trunk/libc/file/fflush.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "stdio.h"
|
||||
int fflush(FILE* file)
|
||||
{
|
||||
if ((file->mode & 3)==FILE_OPEN_READ)
|
||||
return 0;
|
||||
return _msys_file_write(file->filename,file->filesize,file->buffer) ? EOF : 0;
|
||||
}
|
12
programs/develop/metcc/trunk/libc/file/fgetc.c
Normal file
12
programs/develop/metcc/trunk/libc/file/fgetc.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include "stdio.h"
|
||||
int fgetc(FILE* file)
|
||||
{
|
||||
if ((file->mode & 3!=FILE_OPEN_READ) && (file->mode & FILE_OPEN_PLUS==0))
|
||||
return EOF;
|
||||
if (file->filepos>=file->filesize)
|
||||
return EOF;
|
||||
else
|
||||
{
|
||||
return (int)file->buffer[file->filepos++];
|
||||
}
|
||||
}
|
6
programs/develop/metcc/trunk/libc/file/fgetpos.c
Normal file
6
programs/develop/metcc/trunk/libc/file/fgetpos.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "stdio.h"
|
||||
int fgetpos(FILE* file,fpos_t* pos)
|
||||
{
|
||||
*pos=file->filepos;
|
||||
return 0;
|
||||
}
|
89
programs/develop/metcc/trunk/libc/file/fopen.c
Normal file
89
programs/develop/metcc/trunk/libc/file/fopen.c
Normal file
@ -0,0 +1,89 @@
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
FILE* fopen(const char* filename, const char *mode)
|
||||
{
|
||||
FILE* res;
|
||||
int imode;
|
||||
imode=0;
|
||||
if (*mode=='r')
|
||||
{
|
||||
imode=FILE_OPEN_READ;
|
||||
mode++;
|
||||
}else if (*mode=='w')
|
||||
{
|
||||
imode=FILE_OPEN_WRITE;
|
||||
mode++;
|
||||
}else if (*mode=='a')
|
||||
{
|
||||
imode=FILE_OPEN_APPEND;
|
||||
mode++;
|
||||
}else
|
||||
return 0;
|
||||
if (*mode=='t')
|
||||
{
|
||||
imode|=FILE_OPEN_TEXT;
|
||||
mode++;
|
||||
}else if (*mode=='b')
|
||||
mode++;
|
||||
if (*mode=='+')
|
||||
{
|
||||
imode|=FILE_OPEN_PLUS;
|
||||
mode++;
|
||||
}
|
||||
if (*mode!=0)
|
||||
return 0;
|
||||
res=malloc(sizeof(FILE));
|
||||
res->buffer=0;
|
||||
res->buffersize=0;
|
||||
res->filesize=0;
|
||||
res->filepos=0;
|
||||
res->filename=0;
|
||||
res->mode=imode;
|
||||
//check if file exists
|
||||
res=_msys_read_file(filename,0,0,0,&res->filesize);
|
||||
if (res==5)
|
||||
{
|
||||
if ((imode & 3) == FILE_OPEN_READ)
|
||||
{
|
||||
free(res);
|
||||
return 0;
|
||||
}
|
||||
res=_msys_write_file(filename,0,0);
|
||||
if (res!=0)
|
||||
{
|
||||
free(res);
|
||||
return 0;
|
||||
}
|
||||
res->filesize=0;
|
||||
}
|
||||
if (imode & 3==FILE_OPEN_WRITE)
|
||||
{
|
||||
res->buffersize=512;
|
||||
res->buffer=malloc(res->buffersize);
|
||||
if (res->buffer=0)
|
||||
{
|
||||
free(res);
|
||||
return 0;
|
||||
}
|
||||
res->filesize=0;
|
||||
}else
|
||||
{
|
||||
res->buffersize=(res->filesize & (~511))+512;
|
||||
res->buffer=malloc(res->buffersize);
|
||||
if (res->buffer==0)
|
||||
{
|
||||
free(res);
|
||||
return 0;
|
||||
}
|
||||
res=_msys_read_file(filename,0,res->filesize,res->buffer,0);
|
||||
if (res!=0)
|
||||
{
|
||||
free(res->buffer);
|
||||
free(res);
|
||||
}
|
||||
if (imode & 3==FILE_OPEN_APPEND)
|
||||
res->filepos=res->filesize;
|
||||
}
|
||||
res->filename=strdup(filename);
|
||||
return res;
|
||||
}
|
216
programs/develop/metcc/trunk/libc/file/fprintf.c
Normal file
216
programs/develop/metcc/trunk/libc/file/fprintf.c
Normal file
@ -0,0 +1,216 @@
|
||||
#include "stdio.h"
|
||||
const char xdigs_lower[16]="0123456789abcdef";
|
||||
const char xdigs_upper[16]="0123456789ABCDEF";
|
||||
int fprintf(FILE* file, const char* format, ...)
|
||||
{
|
||||
void* arg;
|
||||
int ispoint;
|
||||
int beforepoint;
|
||||
int afterpoint;
|
||||
int longflag;
|
||||
int contflag;
|
||||
int i;
|
||||
long long number;
|
||||
char buffer[50];
|
||||
char* str;
|
||||
arg=&format;
|
||||
arg+=sizeof(const char*);
|
||||
while (*format!='\0')
|
||||
{
|
||||
if (*format!='%')
|
||||
{
|
||||
fputc(*format,file);
|
||||
format++;
|
||||
continue;
|
||||
}
|
||||
ispoint=0;
|
||||
beforepoint=0;
|
||||
afterpoint=0;
|
||||
longflag=0;
|
||||
contflag=1;
|
||||
format++;
|
||||
while (*format && contflag)
|
||||
{
|
||||
switch (*format)
|
||||
{
|
||||
case '.':
|
||||
ispoint=1;
|
||||
format++;
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (ispoint)
|
||||
afterpoint=afterpoint*10+(*format)-'0';
|
||||
else
|
||||
beforepoint=beforepoint*10+(*format)-'0';
|
||||
format++;
|
||||
break;
|
||||
case 'l':
|
||||
if (longflag==0)
|
||||
longflag=1;
|
||||
else
|
||||
longflag=2;
|
||||
format++;
|
||||
break;
|
||||
case 'L':
|
||||
longflag=2;
|
||||
format++;
|
||||
break;
|
||||
case 'f':
|
||||
case 'd':
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 'c':
|
||||
case 's':
|
||||
case '%':
|
||||
contflag=0;
|
||||
break;
|
||||
default:
|
||||
contflag=0;
|
||||
}
|
||||
}
|
||||
if (contflag)
|
||||
break;
|
||||
switch (*format)
|
||||
{
|
||||
case '%':
|
||||
fpuc('%',file);
|
||||
break;
|
||||
case 'd':
|
||||
if (longflag==2)
|
||||
{
|
||||
number=*((long long *)arg);
|
||||
arg+=sizeof(long long);
|
||||
}else
|
||||
{
|
||||
number=*((int*)arg);
|
||||
arg+=sizeof(int);
|
||||
}
|
||||
if (number<0)
|
||||
{
|
||||
beforepoint--;
|
||||
fputc('-',file);
|
||||
number=-number;
|
||||
}
|
||||
i=0;
|
||||
while (number>0)
|
||||
{
|
||||
buffer[i]='0'+number%10;
|
||||
number=number/10;
|
||||
i++;
|
||||
}
|
||||
while (i<beforepoint)
|
||||
{
|
||||
fputc(' ',file);
|
||||
beforepoint--;
|
||||
}
|
||||
while (i>0)
|
||||
{
|
||||
i--;
|
||||
fputc(buffer[i],file);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
fputc(*(char*)arg,file);
|
||||
arg+=sizeof(char);
|
||||
break;
|
||||
case 's':
|
||||
str=*(char**)arg;
|
||||
arg+=sizeof(char*);
|
||||
if (beforepoint==0)
|
||||
beforepoint--;
|
||||
while (*str && beforepoint)
|
||||
{
|
||||
fputc(*str,file);
|
||||
beforepoint--;
|
||||
str++;
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
if (longflag==2)
|
||||
{
|
||||
number=*((long long *)arg);
|
||||
arg+=sizeof(long long);
|
||||
}else
|
||||
{
|
||||
number=*((int*)arg);
|
||||
arg+=sizeof(int);
|
||||
}
|
||||
if (number<0)
|
||||
{
|
||||
beforepoint--;
|
||||
fputc('-',file);
|
||||
number=-number;
|
||||
}
|
||||
i=0;
|
||||
while (number>0)
|
||||
{
|
||||
buffer[i]=xdigs_lower[number & 15];
|
||||
number=number>>4;
|
||||
i++;
|
||||
}
|
||||
while (i<beforepoint)
|
||||
{
|
||||
fputc(' ',file);
|
||||
beforepoint--;
|
||||
}
|
||||
while (i>0)
|
||||
{
|
||||
i--;
|
||||
fputc(buffer[i],file);
|
||||
}
|
||||
break;
|
||||
case 'X':
|
||||
if (longflag==2)
|
||||
{
|
||||
number=*((long long *)arg);
|
||||
arg+=sizeof(long long);
|
||||
}else
|
||||
{
|
||||
number=*((int*)arg);
|
||||
arg+=sizeof(int);
|
||||
}
|
||||
if (number<0)
|
||||
{
|
||||
beforepoint--;
|
||||
fputc('-',file);
|
||||
number=-number;
|
||||
}
|
||||
i=0;
|
||||
while (number>0)
|
||||
{
|
||||
buffer[i]=xdigs_upper[number & 15];
|
||||
number=number>>4;
|
||||
i++;
|
||||
}
|
||||
while (i<beforepoint)
|
||||
{
|
||||
fputc(' ',file);
|
||||
beforepoint--;
|
||||
}
|
||||
while (i>0)
|
||||
{
|
||||
i--;
|
||||
fputc(buffer[i],file);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
if (longflag==2)
|
||||
arg+=10;
|
||||
else if (longflag==1)
|
||||
arg+=8;
|
||||
else
|
||||
arg+=4;
|
||||
break;
|
||||
}
|
||||
format++;
|
||||
}
|
||||
}
|
24
programs/develop/metcc/trunk/libc/file/fputc.c
Normal file
24
programs/develop/metcc/trunk/libc/file/fputc.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include "stdio.h"
|
||||
int fputc(int c,FILE* file)
|
||||
{
|
||||
void* p;
|
||||
if ((file->mode & 3)==FILE_OPEN_READ)
|
||||
return EOF;
|
||||
if ((file->mode & 3)==FILE_OPEN_APPEND)
|
||||
file->filepos=file->filesize;
|
||||
if (file->filepos==file->filesize)
|
||||
{
|
||||
file->filesize++;
|
||||
if (file->filesize>file->buffersize)
|
||||
{
|
||||
p=realloc(file->buffer,file->filesize+file->filesize<<1);
|
||||
if (p==0)
|
||||
return EOF;
|
||||
file->buffersize=file->filesize+file->filesize<<1;
|
||||
file->buffer=p;
|
||||
}
|
||||
}
|
||||
file->buffer[file->filepos]=(char)c;
|
||||
file->filepos++;
|
||||
return 0;
|
||||
}
|
12
programs/develop/metcc/trunk/libc/file/fread.c
Normal file
12
programs/develop/metcc/trunk/libc/file/fread.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include "stdio.h"
|
||||
int fread(void* buffer,int size,int count,FILE* file)
|
||||
{
|
||||
if ((file->mode & 3!=FILE_OPEN_READ) && (file->mode & FILE_OPEN_PLUS==0))
|
||||
return 0;
|
||||
count=count*size;
|
||||
if (count+file->filepos>file->filesize)
|
||||
count=file->filesize-file->filepos;
|
||||
memcpy(buffer,file->buffer+file->filepos,count);
|
||||
file->filepos+=count;
|
||||
return count/size;
|
||||
}
|
188
programs/develop/metcc/trunk/libc/file/fscanf.c
Normal file
188
programs/develop/metcc/trunk/libc/file/fscanf.c
Normal file
@ -0,0 +1,188 @@
|
||||
#include "stdio.h"
|
||||
void skipspaces(FILE* file)
|
||||
{
|
||||
int c;
|
||||
while(1)
|
||||
{
|
||||
c=getc(file);
|
||||
if (c!=' ' && c!='\r' && c!='\n')
|
||||
{
|
||||
ungetc(c,file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
int fscanf(FILE* file,const char* format, ...)
|
||||
{
|
||||
int res;
|
||||
void* arg;
|
||||
int i;
|
||||
int c;
|
||||
int contflag;
|
||||
int longflag;
|
||||
int sign;
|
||||
long long number;
|
||||
long double rnumber;
|
||||
char* str;
|
||||
res=0;
|
||||
arg=&format;
|
||||
arg+=sizeof(const char*);
|
||||
while (*format!='\0')
|
||||
{
|
||||
if (*format!='%')
|
||||
{
|
||||
c=fgetc(file);
|
||||
if (c!=*format)
|
||||
{
|
||||
fungetc(c,file);
|
||||
return -1;
|
||||
}
|
||||
format++;
|
||||
continue;
|
||||
}
|
||||
contflag=1;
|
||||
longflag=0;
|
||||
while (*format && contflag)
|
||||
{
|
||||
switch(*format)
|
||||
{
|
||||
case '.':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
format++;
|
||||
continue;
|
||||
break;
|
||||
case 'l':
|
||||
if (longflag==0)
|
||||
longflag=1;
|
||||
else
|
||||
longflag=2;
|
||||
format++;
|
||||
break;
|
||||
case 'L':
|
||||
longflag=2;
|
||||
format++;
|
||||
break;
|
||||
case 'f':
|
||||
case 'd':
|
||||
case 'c':
|
||||
case 's':
|
||||
case '%':
|
||||
contflag=0;
|
||||
break;
|
||||
default:
|
||||
contflag=0;
|
||||
}
|
||||
}
|
||||
if (contflag)
|
||||
break;
|
||||
switch(*format)
|
||||
{
|
||||
case '%':
|
||||
c=fgetc(file);
|
||||
if (c!='%')
|
||||
{
|
||||
ungetc(c,file);
|
||||
return -1;
|
||||
}
|
||||
res--;
|
||||
break;
|
||||
case 'd':
|
||||
number=0;
|
||||
sign=1;
|
||||
skipspaces(file);
|
||||
c=fgetc(file);
|
||||
if (c=='-')
|
||||
{
|
||||
sign=-1;
|
||||
}else if (c!='+')
|
||||
ungetc(c,file);
|
||||
contflag=0;
|
||||
while(1)
|
||||
{
|
||||
c=fgetc(file);
|
||||
if (c>='0' && c<='9')
|
||||
{
|
||||
contflag++;
|
||||
number=number*10+(c-'0');
|
||||
}else
|
||||
break;
|
||||
}
|
||||
ungetc(c,file);
|
||||
if (!contflag)
|
||||
return res;
|
||||
if (longflag<=1)
|
||||
{
|
||||
*((int*)arg)=number;
|
||||
arg+=sizeof(int);
|
||||
}else
|
||||
{
|
||||
*((long long*)arg)=number;
|
||||
arg+=sizeof(long long);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
c=fgetc(file);
|
||||
if (c==EOF)
|
||||
return res;
|
||||
*((char*)arg)=c;
|
||||
arg+=sizeof(char);
|
||||
break;
|
||||
case 's':
|
||||
skipspaces(file);
|
||||
contflag=0;
|
||||
str=*((char**)arg);
|
||||
arg+=sizeof(char*);
|
||||
while(1)
|
||||
{
|
||||
c=fgetc(file);
|
||||
if (c==EOF || c==' ' || c=='\n' || c=='\r')
|
||||
{
|
||||
ungetc(c,file);
|
||||
break;
|
||||
}
|
||||
*str=c;
|
||||
str++;
|
||||
contflag++;
|
||||
}
|
||||
if (!contflag)
|
||||
return res;
|
||||
break;
|
||||
case 'f':
|
||||
skipspaces(file);
|
||||
// TODO: read real numbers
|
||||
rnumber=0;
|
||||
switch (longflag)
|
||||
{
|
||||
case 0:
|
||||
*((float*)arg)=rnumber;
|
||||
arg+=sizeof(float);
|
||||
break;
|
||||
case 1:
|
||||
*((double*)arg)=rnumber;
|
||||
arg+=sizeof(double);
|
||||
break;
|
||||
case 2:
|
||||
*((long double*)arg)=rnumber;
|
||||
arg+=sizeof(long double);
|
||||
break;
|
||||
default:
|
||||
return res;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
format++;
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
11
programs/develop/metcc/trunk/libc/file/fseek.c
Normal file
11
programs/develop/metcc/trunk/libc/file/fseek.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include "stdio.h"
|
||||
int fseek(FILE* file,long offset,int origin)
|
||||
{
|
||||
if (origin==SEEK_CUR)
|
||||
offset+=file->filepos;
|
||||
else if (origin==SEEK_END)
|
||||
offset+=file->filesize;
|
||||
else if (origin!=SEEK_SET)
|
||||
return EOF;
|
||||
return fsetpos(file,offset);
|
||||
}
|
11
programs/develop/metcc/trunk/libc/file/fsetpos.c
Normal file
11
programs/develop/metcc/trunk/libc/file/fsetpos.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include "stdio.h"
|
||||
int fsetpos(FILE* file,const fpos_t * pos)
|
||||
{
|
||||
if (*pos>=0)
|
||||
{
|
||||
file->filepos=*pos;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return EOF;
|
||||
}
|
5
programs/develop/metcc/trunk/libc/file/ftell.c
Normal file
5
programs/develop/metcc/trunk/libc/file/ftell.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include "stdio.h"
|
||||
long ftell(FILE* file)
|
||||
{
|
||||
return file->filepos;
|
||||
}
|
23
programs/develop/metcc/trunk/libc/file/fwrite.c
Normal file
23
programs/develop/metcc/trunk/libc/file/fwrite.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include "stdio.h"
|
||||
int fwrite(const void* buffer,int size,int count,FILE* file)
|
||||
{
|
||||
void* p;
|
||||
if ((file->mode & 3==FILE_OPEN_READ) && (file->mode & FILE_OPEN_PLUS==0))
|
||||
return 0;
|
||||
if (file->mode & 3==FILE_OPEN_APPEND)
|
||||
file->filepos=file->filesize;
|
||||
count=count*size;
|
||||
if (file->buffersize<file->filepos+count)
|
||||
{
|
||||
p=realloc(file->buffer,(file->filepos+count)+(file->filepos+count)<<1);
|
||||
if (p==0)
|
||||
return 0;
|
||||
file->buffer=p;
|
||||
file->buffersize=(file->filepos+count)+(file->filepos+count)<<1;
|
||||
}
|
||||
if (file->filesize<file->filepos+count)
|
||||
file->filesize=file->filepos+count;
|
||||
memcpy(file->buffer+file->filepos,buffer,count);
|
||||
file->filepos+=count;
|
||||
return count;
|
||||
}
|
5
programs/develop/metcc/trunk/libc/file/rewind.c
Normal file
5
programs/develop/metcc/trunk/libc/file/rewind.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include "stdio.h"
|
||||
void rewind(FILE* file)
|
||||
{
|
||||
file->filepos=0;
|
||||
}
|
11
programs/develop/metcc/trunk/libc/file/ungetc.c
Normal file
11
programs/develop/metcc/trunk/libc/file/ungetc.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include "stdio.h"
|
||||
int ungetc(int c,FILE* file)
|
||||
{
|
||||
if (c==EOF)
|
||||
return EOF;
|
||||
if (file->filepos<=0 || file->filepos>file->filesize)
|
||||
return EOF;
|
||||
file->filepos--;
|
||||
file->buffer[file->filepos]=(char)c;
|
||||
return c;
|
||||
}
|
88
programs/develop/metcc/trunk/libc/include/mesys.h
Normal file
88
programs/develop/metcc/trunk/libc/include/mesys.h
Normal file
@ -0,0 +1,88 @@
|
||||
#ifndef mesys_h
|
||||
#define mesys_h
|
||||
#ifdef GNUC
|
||||
#define stdcall __stdcall
|
||||
#else
|
||||
#define stdcall __attribute__ ((__stdcall))
|
||||
#endif
|
||||
extern void stdcall _msys_draw_window(int xcoord,int ycoord, int xsize,
|
||||
int ysize,int workcolor,int type,
|
||||
int captioncolor,int windowtype,int bordercolor);
|
||||
extern int stdcall _msys_read_file(char* filename,int fileoffset,int size,void* data,
|
||||
int* filesize);
|
||||
extern int stdcall _msys_write_file(char* filename,int size,void* data);
|
||||
extern void stdcall _msys_run_program(char* filename,char* parameters);
|
||||
extern void stdcall _msys_debug_out(int c);
|
||||
extern void debug_out_str(char* str);
|
||||
extern void stdcall _msys_set_background_size(int xsize,int ysize);
|
||||
extern void stdcall _msys_write_background_mem(int pos,int color);
|
||||
extern void stdcall _msys_draw_background(void);
|
||||
extern void stdcall _msys_set_background_draw_type(int type);
|
||||
extern void stdcall _msys_background_blockmove(void* src,int bgr_pos, int count);
|
||||
extern void stdcall _msys_draw_bar(int x, int y, int xsize, int ysize, int color);
|
||||
extern void stdcall _msys_make_button(int x, int y, int xsize, int ysize, int id, int color);
|
||||
extern int stdcall _msys_get_button_id(void);
|
||||
extern int stdcall _msys_get_system_clock(void);
|
||||
extern int stdcall _msys_get_date(void);
|
||||
extern void stdcall _msys_delay(int m);
|
||||
extern void stdcall _msys_dga_get_resolution(int* xres, int* yres, int* bpp, int* bpscan);
|
||||
extern int stdcall _msys_wait_for_event_infinite(void);
|
||||
extern int stdcall _msys_check_for_event(void);
|
||||
extern int stdcall _msys_wait_for_event(int time);
|
||||
extern void stdcall _msys_set_wanted_events(int ev);
|
||||
extern void stdcall _msys_exit(void);
|
||||
extern void stdcall _msys_putimage(int x, int y, int xsize, int ysize, void* image);
|
||||
extern void stdcall _msys_send_message(int pid, void* msg, int size);
|
||||
extern void stdcall _msys_define_receive_area(void* area, int size);
|
||||
extern int stdcall _msys_get_irq_owner(int irq);
|
||||
extern int stdcall _msys_get_data_read_by_irq(int irq, int* size, void* data);
|
||||
extern int stdcall _msys_send_data_to_device(int port, unsigned char val);
|
||||
extern int stdcall _msys_receive_data_from_device(int port,unsigned char* data);
|
||||
extern void stdcall _msys_program_irq(void* intrtable, int irq);
|
||||
extern void stdcall _msys_reserve_irq(int irq);
|
||||
extern void stdcall _msys_free_irq(int irq);
|
||||
extern int stdcall _msys_reserve_port_area(int start,int end);
|
||||
extern int stdcall _msys_free_port_area(int start,int end);
|
||||
extern int stdcall _msys_get_key(void);
|
||||
extern void stdcall _msys_set_keyboard_mode(int mode);
|
||||
extern void stdcall _msys_line(int x1,int y1,int x2,int y2,int color);
|
||||
extern void stdcall _msys_midi_reset(void);
|
||||
extern void stdcall _msys_midi_send(int data);
|
||||
extern int stdcall _msys_get_pci_version(void);
|
||||
extern int stdcall _msys_get_last_pci_bus(void);
|
||||
extern int stdcall _msys_get_pci_access_mechanism(void);
|
||||
extern int stdcall _msys_pci_read_config_byte(int bus,int dev,int fn,int reg);
|
||||
extern int stdcall _msys_pci_read_config_word(int bus,int dev,int fn,int reg);
|
||||
extern int stdcall _msys_pci_read_config_dword(int bus,int dev,int fn,int reg);
|
||||
extern int stdcall _msys_pci_write_config_byte(int bus,int dev,int fn,int reg,int value);
|
||||
extern int stdcall _msys_pci_write_config_word(int bus,int dev,int fn,int reg,int value);
|
||||
extern int stdcall _msys_pci_write_config_value(int bus,int dev,int fn,int reg,int value);
|
||||
extern int stdcall _msys_putpixel(int x,int y,int color);
|
||||
typedef struct {
|
||||
int cpu_usage;
|
||||
int window_pos_info;
|
||||
char name[12];
|
||||
int memstart;
|
||||
int memused;
|
||||
int pid;
|
||||
int winx_start;
|
||||
int winy_start;
|
||||
int winx_size;
|
||||
int winy_size;
|
||||
int slot_info;
|
||||
} process_table_entry;
|
||||
extern int stdcall _msys_get_process_table(process_table_entry* proctab,int pid);
|
||||
extern int stdcall _msys_get_screen_size(int* x,int* y);
|
||||
extern void stdcall _msys_sound_load_block(void* blockptr);
|
||||
extern void stdcall _msys_sound_play_block(void);
|
||||
extern void stdcall _msys_sound_set_channels(int channels);
|
||||
extern void stdcall _msys_sound_set_data_size(int size);
|
||||
extern void stdcall _msys_sound_set_frequency(int frequency);
|
||||
extern void stdcall _msys_sound_speaker_play(void* data);
|
||||
extern void stdcall _msys_write_text(int x,int y,int color,char* text,int len);
|
||||
extern void* stdcall _msys_start_thread(void (* func_ptr)(void),int stack_size,int* pid);
|
||||
extern void stdcall _msys_window_redraw(int status);
|
||||
extern void* stdcall malloc(int);
|
||||
extern void stdcall free(void*);
|
||||
extern void* stdcall realloc(void*,int);
|
||||
#endif
|
38
programs/develop/metcc/trunk/libc/include/stdio.h
Normal file
38
programs/develop/metcc/trunk/libc/include/stdio.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef stdio_h
|
||||
#define stdio_h
|
||||
#include "mesys.h"
|
||||
typedef struct {
|
||||
char* buffer;
|
||||
int buffersize;
|
||||
int filesize;
|
||||
int filepos;
|
||||
char* filename;
|
||||
int mode;
|
||||
} FILE;
|
||||
#define FILE_OPEN_READ 0
|
||||
#define FILE_OPEN_WRITE 1
|
||||
#define FILE_OPEN_APPEND 2
|
||||
#define FILE_OPEN_TEXT 4
|
||||
#define FILE_OPEN_PLUS 8
|
||||
#define EOF -1
|
||||
extern FILE* fopen(const char* filename, const char *mode);
|
||||
extern int fclose(FILE* file);
|
||||
extern int feof(FILE* file);
|
||||
extern int fflush(FILE* file);
|
||||
extern int fgetc(FILE* file);
|
||||
typedef int fpos_t;
|
||||
extern int fgetpos(FILE* file,fpos_t* pos);
|
||||
extern int fsetpos(FILE* file,const fpos_t* pos);
|
||||
extern int fputc(int c,FILE* file);
|
||||
extern int fread(void* buffer,int size,int count,FILE* file);
|
||||
extern int fwrite(const void* buffer,int size,int count,FILE* file);
|
||||
extern long ftell(FILE* file);
|
||||
#define SEEK_CUR 0
|
||||
#define SEEK_END 1
|
||||
#define SEEK_SET 2
|
||||
extern int fseek(FILE* file,long offset,int origin);
|
||||
extern void rewind(FILE* file);
|
||||
extern int fprintf(FILE* file, const char* format, ...);
|
||||
extern int fscanf(FILE* file,const char* format, ...);
|
||||
extern int ungetc(int c,FILE* file);
|
||||
#endif
|
25
programs/develop/metcc/trunk/libc/include/string.h
Normal file
25
programs/develop/metcc/trunk/libc/include/string.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef string_h
|
||||
#define string_h
|
||||
extern void* memchr(const void*,int,int);
|
||||
extern int memcmp(const void*,const void*,int);
|
||||
extern void* memcpy(void*,const void*,int);
|
||||
extern void* memmove(void*,const void*,int);
|
||||
extern void* memset(void*,int,int);
|
||||
extern char* strcat(char*,const char*);
|
||||
extern char* strchr(const char*,int);
|
||||
extern int strcmp(const char*,const char*);
|
||||
extern int strcoll(const char*,const char*);
|
||||
extern char* strcpy(char*,const char*);
|
||||
extern int strcspn(const char*,const char*);
|
||||
extern int strlen(const char*);
|
||||
extern char* strncat(char*,const char*,int);
|
||||
extern int strncmp(const char*,const char*,int);
|
||||
extern char* strncpy(char*,const char*,int);
|
||||
extern char* strpbrk(const char*,const char*);
|
||||
extern char* strrchr(const char*,int);
|
||||
extern int strspn(const char*,const char*);
|
||||
extern char* strstr(const char*,const char*);
|
||||
extern char* strtok(char*,const char*);
|
||||
extern int strxfrm(char*,const char*,int);
|
||||
extern char* strdup(const char*);
|
||||
#endif
|
536
programs/develop/metcc/trunk/libc/mem/memalloc.asm
Normal file
536
programs/develop/metcc/trunk/libc/mem/memalloc.asm
Normal file
@ -0,0 +1,536 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public malloc
|
||||
public free
|
||||
public realloc
|
||||
public mf_init
|
||||
;multithread: ;uncomment this for thread-safe version
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Memory allocator for MenuetOS ;;
|
||||
;; Halyavin Andrey halyavin@land.ru, 2006 ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; allocated mem block structure ;;
|
||||
;; +0: bit 0 - used flag ;;
|
||||
;; bits 31..1 - block size ;;
|
||||
;; +4: address of prev block ;;
|
||||
;; +8 .. +(blocksize) - allocated memory ;;
|
||||
;; +(blocksize) - next block ;;
|
||||
;; ;;
|
||||
;; free mem block structure ;;
|
||||
;; +0: bit 0 - used flag ;;
|
||||
;; bits 31..1 - block size ;;
|
||||
;; +4: address of prev block ;;
|
||||
;; +8: prev free block ;;
|
||||
;; +12: next free block ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
memblock.size=0
|
||||
memblock.prevblock=4
|
||||
memblock.prevfreeblock=8
|
||||
memblock.nextfreeblock=12
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; mf_init ;;
|
||||
;; Initialize memory map for dynamic use ;;
|
||||
;; input: eax: starting address or 0 ;;
|
||||
;; output: none ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
mf_init:
|
||||
push ebx
|
||||
push ecx
|
||||
test eax,eax
|
||||
jnz .noautodet
|
||||
sub esp,1024
|
||||
mov ebx,esp
|
||||
mov ecx,-1
|
||||
mov eax,9
|
||||
int 0x40
|
||||
mov eax,[esp+26]
|
||||
add esp,1024
|
||||
.noautodet:
|
||||
add eax,15
|
||||
and eax,not 15
|
||||
mov [heapsmallblocks],eax
|
||||
add eax,2048
|
||||
mov [heapstart],eax
|
||||
mov [heapfreelist],eax
|
||||
mov [heaplastblock],eax
|
||||
|
||||
mov ecx,eax
|
||||
if defined heapstartsize
|
||||
add ecx,heapstartsize
|
||||
else
|
||||
add ecx,4096
|
||||
end if
|
||||
add ecx,4095
|
||||
and ecx,not 4095
|
||||
push eax
|
||||
mov eax,64
|
||||
mov ebx,1
|
||||
int 0x40
|
||||
pop eax
|
||||
mov [eax+memblock.prevblock],dword 0
|
||||
mov [heapend],ecx
|
||||
mov [eax+memblock.size],ecx
|
||||
sub [eax+memblock.size],eax
|
||||
xor ebx,ebx
|
||||
mov dword [eax+memblock.prevfreeblock],heapfreelist-memblock.nextfreeblock
|
||||
mov [eax+memblock.nextfreeblock],ebx
|
||||
mov [heapmutex],ebx
|
||||
push edi
|
||||
mov edi,[heapsmallblocks]
|
||||
mov ecx,512
|
||||
xor eax,eax
|
||||
rep stosd
|
||||
pop edi
|
||||
pop ecx
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
if defined multithread
|
||||
heaplock:
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
mov eax,68
|
||||
mov ebx,1
|
||||
.loop:
|
||||
xchg ecx,[heapmutex]
|
||||
test ecx,ecx
|
||||
jz .endloop
|
||||
int 0x40 ;change task
|
||||
jmp .loop
|
||||
.endloop:
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
ret
|
||||
|
||||
heapunlock:
|
||||
mov [heapmutex],dword 0
|
||||
ret
|
||||
end if
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; heap_split_block ;;
|
||||
;; Split free block to allocated block and free one. ;;
|
||||
;; input: ;;
|
||||
;; eax - size of allocated block ;;
|
||||
;; ebx - block ;;
|
||||
;; output: ;;
|
||||
;; eax - real size of allocated block ;;
|
||||
;; ebx - pointer to new block ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
heap_split_block:
|
||||
push ecx
|
||||
mov ecx,[ebx+memblock.size]
|
||||
sub ecx,16
|
||||
cmp ecx,eax
|
||||
jge .norm
|
||||
inc dword [ebx+memblock.size]
|
||||
mov eax,ecx
|
||||
xor ebx,ebx
|
||||
pop ecx
|
||||
ret
|
||||
.norm:
|
||||
add ecx,16
|
||||
mov [ebx+memblock.size],eax
|
||||
inc dword [ebx+memblock.size]
|
||||
mov [ebx+eax+memblock.prevblock],ebx
|
||||
add ebx,eax
|
||||
sub ecx,eax
|
||||
mov [ebx+memblock.size],ecx
|
||||
mov ecx,eax
|
||||
mov eax,ebx
|
||||
call heap_fix_right
|
||||
mov eax,ecx
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; heap_add_free_block ;;
|
||||
;; Add free block to one of free block lists. ;;
|
||||
;; input: ;;
|
||||
;; eax - address of free block ;;
|
||||
;; output: ;;
|
||||
;; none ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
heap_add_free_block:
|
||||
cmp dword [eax+memblock.size],4096
|
||||
push ebx
|
||||
jge .bigblock
|
||||
mov ebx,[eax+memblock.size]
|
||||
shr ebx,1
|
||||
add ebx,[heapsmallblocks]
|
||||
push dword [ebx]
|
||||
pop dword [eax+memblock.nextfreeblock]
|
||||
mov [ebx],eax
|
||||
mov dword [eax+memblock.prevfreeblock],ebx
|
||||
sub dword [eax+memblock.prevfreeblock],memblock.nextfreeblock
|
||||
mov ebx,[eax+memblock.nextfreeblock]
|
||||
test ebx,ebx
|
||||
jz .no_next_block
|
||||
mov [ebx+memblock.prevfreeblock],eax
|
||||
.no_next_block:
|
||||
pop ebx
|
||||
ret
|
||||
.bigblock:
|
||||
mov ebx,[heapfreelist]
|
||||
mov [eax+memblock.nextfreeblock],ebx
|
||||
mov [heapfreelist],eax
|
||||
mov dword [eax+memblock.prevfreeblock],heapfreelist-memblock.nextfreeblock
|
||||
; mov ebx,[eax+memblock.nextfreeblock]
|
||||
test ebx,ebx
|
||||
jz .no_next_big_block
|
||||
mov [ebx+memblock.prevfreeblock],eax
|
||||
.no_next_big_block:
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; heap_remove_block ;;
|
||||
;; Remove free block from the list of free blocks. ;;
|
||||
;; input: ;;
|
||||
;; eax - free block ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
heap_remove_block:
|
||||
push ebx
|
||||
push ecx
|
||||
mov ecx,[eax+memblock.prevfreeblock]
|
||||
mov ebx,[eax+memblock.nextfreeblock]
|
||||
mov [ecx+memblock.nextfreeblock],ebx
|
||||
test ebx,ebx
|
||||
jz .no_next_block
|
||||
mov [ebx+memblock.prevfreeblock],ecx
|
||||
.no_next_block:
|
||||
pop ecx
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; mf_alloc
|
||||
;; allocates a block of memory in heap
|
||||
;; intput: eax: size of block
|
||||
;; output: eax: address of allocated memory block or 0 if there's no mem.
|
||||
;; allocator will not create new nodes that contain less that 8b of space,
|
||||
;; and minimal allocation is actually 16 bytes - 8 for node and 8 for user.
|
||||
;; allocator will never create non-aligned memory blocks.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
mf_alloc:
|
||||
test eax,eax
|
||||
jg .not_null ; test that we are not allocating null size block
|
||||
xor eax,eax
|
||||
ret
|
||||
.not_null:
|
||||
if defined multithread
|
||||
call heaplock
|
||||
end if
|
||||
push edi
|
||||
; push edx
|
||||
push ecx
|
||||
push ebx
|
||||
add eax,7
|
||||
and eax,not 7 ; make sure that block size is aligned
|
||||
|
||||
lea edi,[eax+8] ; desired block size
|
||||
cmp edi,4096
|
||||
jge .general_cycle
|
||||
|
||||
mov ebx,[heapsmallblocks]
|
||||
xor ecx,ecx
|
||||
shr edi,1
|
||||
|
||||
.smallloop:
|
||||
cmp [ebx+edi],ecx
|
||||
jnz .smallblockfound
|
||||
add edi,4
|
||||
cmp edi,2048
|
||||
jl .smallloop
|
||||
lea edi,[eax+8]
|
||||
jmp .general_cycle
|
||||
|
||||
.smallblockfound:
|
||||
lea ecx,[eax+8]
|
||||
mov eax,[ebx+edi]
|
||||
call heap_remove_block
|
||||
mov ebx,eax
|
||||
xchg eax,ecx
|
||||
call heap_split_block
|
||||
test ebx,ebx
|
||||
jz .perfect_small_block
|
||||
mov eax,ebx
|
||||
call heap_add_free_block
|
||||
.perfect_small_block:
|
||||
lea eax,[ecx+8]
|
||||
jmp .ret
|
||||
|
||||
.general_cycle:
|
||||
;edi - size needed
|
||||
mov eax,[heapfreelist]
|
||||
|
||||
.loop:
|
||||
test eax,eax
|
||||
jz .new_mem
|
||||
cmp [eax+memblock.size],edi
|
||||
jge .blockfound
|
||||
mov eax,[eax+memblock.nextfreeblock]
|
||||
jmp .loop
|
||||
|
||||
.blockfound:
|
||||
call heap_remove_block
|
||||
mov ebx,eax
|
||||
mov ecx,eax
|
||||
mov eax,edi
|
||||
call heap_split_block
|
||||
test ebx,ebx
|
||||
jz .perfect_block
|
||||
mov eax,ebx
|
||||
call heap_add_free_block
|
||||
.perfect_block:
|
||||
lea eax,[ecx+8]
|
||||
.ret:
|
||||
if defined multithread
|
||||
call heapunlock
|
||||
end if
|
||||
pop ebx
|
||||
pop ecx
|
||||
; pop edx
|
||||
pop edi
|
||||
ret
|
||||
|
||||
.new_mem:
|
||||
mov eax,edi
|
||||
add eax,4095
|
||||
and eax,not 4095
|
||||
mov ecx,[heapend]
|
||||
add [heapend],eax
|
||||
push eax
|
||||
mov eax,64
|
||||
push ebx
|
||||
push ecx
|
||||
mov ecx,[heapend]
|
||||
mov ebx,1
|
||||
int 0x40
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
mov [ecx+memblock.size],eax
|
||||
mov eax,[heaplastblock]
|
||||
mov [ecx+memblock.prevblock],eax
|
||||
mov [heaplastblock],ecx
|
||||
mov eax,ecx
|
||||
call heap_add_free_block
|
||||
jmp .general_cycle
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; heap_fix_right ;;
|
||||
;; input: ;;
|
||||
;; eax - pointer to free block ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
heap_fix_right:
|
||||
push ebx
|
||||
mov ebx,eax
|
||||
add ebx,[eax+memblock.size]
|
||||
cmp ebx,[heapend]
|
||||
jz .endblock
|
||||
mov [ebx+memblock.prevblock],eax
|
||||
pop ebx
|
||||
ret
|
||||
.endblock:
|
||||
mov [heaplastblock],eax
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; heap_merge_left ;;
|
||||
;; input: ;;
|
||||
;; eax - pointer to free block ;;
|
||||
;; output: ;;
|
||||
;; eax - pointer to merged block ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
heap_merge_left:
|
||||
push ebx
|
||||
mov ebx,[eax+memblock.prevblock]
|
||||
test ebx,ebx
|
||||
jz .ret
|
||||
test byte [ebx+memblock.size],1
|
||||
jnz .ret
|
||||
xchg eax,ebx
|
||||
call heap_remove_block
|
||||
mov ebx,[ebx+memblock.size]
|
||||
add [eax+memblock.size],ebx
|
||||
call heap_fix_right
|
||||
.ret:
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; heap_merge_right ;;
|
||||
;; input: ;;
|
||||
;; eax - pointer to free block ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
heap_merge_right:
|
||||
push ebx
|
||||
mov ebx,eax
|
||||
add ebx,[eax+memblock.size]
|
||||
cmp ebx,[heapend]
|
||||
jz .ret
|
||||
test byte [ebx+memblock.size],1
|
||||
jnz .ret
|
||||
xchg eax,ebx
|
||||
call heap_remove_block
|
||||
xchg eax,ebx
|
||||
mov ebx,[ebx+memblock.size]
|
||||
add [eax+memblock.size],ebx
|
||||
call heap_fix_right
|
||||
.ret:
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; mf_free ;;
|
||||
;; input: ;;
|
||||
;; eax - pointer ;;
|
||||
;; output: ;;
|
||||
;; eax=1 - ok ;;
|
||||
;; eax=0 - failed ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
mf_free:
|
||||
test eax,eax
|
||||
jnz .no_null
|
||||
inc eax
|
||||
ret
|
||||
.no_null:
|
||||
if defined multithread
|
||||
call heaplock
|
||||
end if
|
||||
sub eax,8
|
||||
dec dword [eax+memblock.size]
|
||||
call heap_merge_left
|
||||
call heap_merge_right
|
||||
call heap_add_free_block
|
||||
.ret:
|
||||
if defined multithread
|
||||
call heapunlock
|
||||
end if
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; heap_try_reloc
|
||||
;; input:
|
||||
;; eax - address
|
||||
;; ebx - new size
|
||||
;; output:
|
||||
;; ebx=1 - ok
|
||||
;; ebx=0 - failed
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
heap_try_reloc:
|
||||
push eax
|
||||
sub eax,8
|
||||
add ebx,15
|
||||
dec dword [eax+memblock.size]
|
||||
and ebx,not 7
|
||||
cmp [eax+memblock.size],ebx
|
||||
jge .truncate
|
||||
push ebx
|
||||
mov ebx,eax
|
||||
add ebx,[eax+memblock.size]
|
||||
cmp ebx,[heapend]
|
||||
jz .fail ;todo: we can allocate new mem here
|
||||
test [ebx+memblock.size],byte 1
|
||||
jnz .fail
|
||||
xchg eax,ebx
|
||||
call heap_remove_block
|
||||
mov eax,[eax+memblock.size]
|
||||
add [ebx+memblock.size],eax
|
||||
mov eax,ebx
|
||||
call heap_fix_right
|
||||
pop ebx
|
||||
.truncate:
|
||||
xchg eax,ebx
|
||||
call heap_split_block
|
||||
test ebx,ebx
|
||||
jz .no_last_block
|
||||
mov eax,ebx
|
||||
call heap_add_free_block
|
||||
call heap_merge_right
|
||||
.no_last_block:
|
||||
xor ebx,ebx
|
||||
pop eax
|
||||
inc ebx
|
||||
ret
|
||||
.fail:
|
||||
pop ebx
|
||||
xor ebx,ebx
|
||||
pop eax
|
||||
inc dword [eax-8+memblock.size]
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; mf_realloc
|
||||
;; input:
|
||||
;; eax - pointer
|
||||
;; ebx - new size
|
||||
;; output:
|
||||
;; eax - new pointer
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
mf_realloc:
|
||||
push ebx
|
||||
if defined multithread
|
||||
call heaplock
|
||||
end if
|
||||
call heap_try_reloc
|
||||
test ebx,ebx
|
||||
jnz .ret
|
||||
;allocate new memory
|
||||
push eax
|
||||
mov eax,[esp+4]
|
||||
call mf_alloc
|
||||
test eax,eax
|
||||
jz .fail
|
||||
push esi
|
||||
push edi
|
||||
push ecx
|
||||
mov edi,eax
|
||||
mov esi,[esp+12]
|
||||
mov ecx,[esi-8+memblock.size]
|
||||
shr ecx,2
|
||||
rep movsd
|
||||
pop ecx
|
||||
pop edi
|
||||
pop esi
|
||||
xchg eax,[esp]
|
||||
call mf_free
|
||||
.fail:
|
||||
pop eax
|
||||
.ret:
|
||||
if defined multithread
|
||||
call heapunlock
|
||||
end if
|
||||
pop ebx
|
||||
ret
|
||||
;C entries
|
||||
malloc:
|
||||
mov eax,[esp+4]
|
||||
call mf_alloc
|
||||
ret
|
||||
free:
|
||||
mov eax,[esp+4]
|
||||
call mf_free
|
||||
ret
|
||||
realloc:
|
||||
mov edx,ebx
|
||||
mov eax,[esp+4]
|
||||
mov ebx,[esp+8]
|
||||
call mf_realloc
|
||||
mov ebx,edx
|
||||
ret
|
||||
section '.bss' writeable
|
||||
heapsmallblocks rd 1
|
||||
heapstart rd 1
|
||||
heapend rd 1
|
||||
heapfreelist rd 1
|
||||
heapmutex rd 1
|
||||
heaplastblock rd 1
|
58
programs/develop/metcc/trunk/libc/mesys/backgr.asm
Normal file
58
programs/develop/metcc/trunk/libc/mesys/backgr.asm
Normal file
@ -0,0 +1,58 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_set_background_size
|
||||
_msys_set_background_size:
|
||||
;arg1 - xsize
|
||||
;arg2 - ysize
|
||||
push ebx
|
||||
mov ecx,[esp+8]
|
||||
mov edx,[esp+12]
|
||||
mov eax,15
|
||||
mov ebx,1
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 8
|
||||
public _msys_write_background_mem
|
||||
_msys_write_background_mem:
|
||||
;arg1 - pos
|
||||
;arg2 - color
|
||||
push ebx
|
||||
mov eax,15
|
||||
mov ebx,2
|
||||
mov ecx,[esp+8]
|
||||
mov edx,[esp+12]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 8
|
||||
public _msys_draw_background
|
||||
_msys_draw_background:
|
||||
mov edx,ebx
|
||||
mov eax,15
|
||||
mov ebx,3
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret
|
||||
public _msys_set_background_draw_type
|
||||
_msys_set_background_draw_type:
|
||||
;arg1 - type
|
||||
mov edx,ebx
|
||||
mov eax,15
|
||||
mov ebx,4
|
||||
mov ecx,[esp+4]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 4
|
||||
public _msys_background_blockmove
|
||||
_msys_background_blockmove:
|
||||
;arg1 - source
|
||||
;arg2 - position in dest
|
||||
;arg3 - size
|
||||
push ebx esi
|
||||
mov eax,15
|
||||
mov ebx,5
|
||||
mov ecx,[esp+12]
|
||||
mov edx,[esp+16]
|
||||
mov esi,[esp+20]
|
||||
int 0x40
|
||||
pop esi ebx
|
||||
ret 12
|
36
programs/develop/metcc/trunk/libc/mesys/button.asm
Normal file
36
programs/develop/metcc/trunk/libc/mesys/button.asm
Normal file
@ -0,0 +1,36 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_make_button
|
||||
_msys_make_button:
|
||||
;arg1 - x
|
||||
;arg2 - y
|
||||
;arg3 - xsize
|
||||
;arg4 - ysize
|
||||
;arg5 - id
|
||||
;arg6 - color
|
||||
push ebx esi
|
||||
mov ebx,[esp+12]
|
||||
shl ebx,16
|
||||
mov bx,[esp+20]
|
||||
mov ecx,[esp+16]
|
||||
shl ecx,16
|
||||
mov cx,[esp+24]
|
||||
mov edx,[esp+28]
|
||||
mov esi,[esp+32]
|
||||
mov eax,8
|
||||
int 0x40
|
||||
pop esi ebx
|
||||
ret 24
|
||||
|
||||
public _msys_get_button_id
|
||||
_msys_get_button_id:
|
||||
mov eax,17
|
||||
int 0x40
|
||||
test al,al
|
||||
jnz .no_button
|
||||
shr eax,8
|
||||
ret
|
||||
.no_button:
|
||||
xor eax,eax
|
||||
dec eax
|
||||
ret
|
7
programs/develop/metcc/trunk/libc/mesys/clock.asm
Normal file
7
programs/develop/metcc/trunk/libc/mesys/clock.asm
Normal file
@ -0,0 +1,7 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_get_system_clock
|
||||
_msys_get_system_clock:
|
||||
mov eax,3
|
||||
int 0x40
|
||||
ret
|
7
programs/develop/metcc/trunk/libc/mesys/date.asm
Normal file
7
programs/develop/metcc/trunk/libc/mesys/date.asm
Normal file
@ -0,0 +1,7 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_get_date
|
||||
_msys_get_date:
|
||||
mov eax,29
|
||||
int 0x40
|
||||
ret
|
13
programs/develop/metcc/trunk/libc/mesys/debug_board.asm
Normal file
13
programs/develop/metcc/trunk/libc/mesys/debug_board.asm
Normal file
@ -0,0 +1,13 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
|
||||
public _msys_debug_out
|
||||
_msys_debug_out:
|
||||
;arg1 - char to out
|
||||
push ebx
|
||||
mov ecx,[esp+8]
|
||||
mov ebx,1
|
||||
mov eax,63
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 4
|
9
programs/develop/metcc/trunk/libc/mesys/debug_board_.c
Normal file
9
programs/develop/metcc/trunk/libc/mesys/debug_board_.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include "mesys.h"
|
||||
void debug_out_str(char* str)
|
||||
{
|
||||
while (*str!='\0')
|
||||
{
|
||||
_msys_debug_out(*str);
|
||||
str++;
|
||||
}
|
||||
}
|
11
programs/develop/metcc/trunk/libc/mesys/delay.asm
Normal file
11
programs/develop/metcc/trunk/libc/mesys/delay.asm
Normal file
@ -0,0 +1,11 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_delay
|
||||
_msys_delay:
|
||||
;arg1 - time
|
||||
mov edx,ebx
|
||||
mov eax,5
|
||||
mov ebx,[esp+4]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 4
|
34
programs/develop/metcc/trunk/libc/mesys/dga.asm
Normal file
34
programs/develop/metcc/trunk/libc/mesys/dga.asm
Normal file
@ -0,0 +1,34 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_dga_get_resolution
|
||||
_msys_dga_get_resolution:
|
||||
;arg1 - *xres
|
||||
;arg2 - *yres
|
||||
;arg3 - *bpp
|
||||
;arg4 - *bpscan
|
||||
mov edx,ebx
|
||||
|
||||
mov eax,61
|
||||
mov ebx,1
|
||||
int 0x40
|
||||
mov ebx,[esp+8]
|
||||
mov [ebx],ax
|
||||
mov word [ebx+2],0
|
||||
shr eax,16
|
||||
mov ebx,[esp+4]
|
||||
mov [ebx],eax
|
||||
|
||||
mov eax,61
|
||||
mov ebx,2
|
||||
int 0x40
|
||||
mov ebx,[esp+12]
|
||||
mov [ebx],eax
|
||||
|
||||
mov eax,61
|
||||
mov ebx,3
|
||||
int 0x40
|
||||
mov ebx,[esp+16]
|
||||
mov [ebx],eax
|
||||
|
||||
mov ebx,edx
|
||||
ret 16
|
21
programs/develop/metcc/trunk/libc/mesys/draw_bar.asm
Normal file
21
programs/develop/metcc/trunk/libc/mesys/draw_bar.asm
Normal file
@ -0,0 +1,21 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_draw_bar
|
||||
_msys_draw_bar:
|
||||
;arg1 - x
|
||||
;arg2 - y
|
||||
;arg3 - xsize
|
||||
;arg4 - ysize
|
||||
;arg5 - color
|
||||
push ebx
|
||||
mov eax,13
|
||||
mov ebx,[esp+8]
|
||||
shl ebx,16
|
||||
mov bx,[esp+16]
|
||||
mov ecx,[esp+12]
|
||||
shl ecx,16
|
||||
mov cx,[esp+20]
|
||||
mov edx,[esp+24]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 20
|
21
programs/develop/metcc/trunk/libc/mesys/draw_image.asm
Normal file
21
programs/develop/metcc/trunk/libc/mesys/draw_image.asm
Normal file
@ -0,0 +1,21 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_putimage
|
||||
_msys_putimage:
|
||||
;arg1 - x
|
||||
;arg2 - y
|
||||
;arg3 - xsize
|
||||
;arg4 - ysize
|
||||
;arg5 - image
|
||||
push ebx
|
||||
mov ebx,[esp+24]
|
||||
mov ecx,[esp+16]
|
||||
shl ecx,16
|
||||
mov ecx,[esp+20]
|
||||
mov ebx,[esp+8]
|
||||
shl ebx,16
|
||||
mov ebx,[esp+12]
|
||||
mov eax,7
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 20
|
35
programs/develop/metcc/trunk/libc/mesys/draw_window.asm
Normal file
35
programs/develop/metcc/trunk/libc/mesys/draw_window.asm
Normal file
@ -0,0 +1,35 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
|
||||
public _msys_draw_window
|
||||
_msys_draw_window:
|
||||
;arg1 - xcoord
|
||||
;arg2 - ycoord
|
||||
;arg3 - xsize
|
||||
;arg4 - ysize
|
||||
;arg5 - workcolor
|
||||
;arg6 - type
|
||||
;arg7 - captioncolor
|
||||
;arg8 - windowtype
|
||||
;arg9 - bordercolor
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
push ebx esi edi
|
||||
mov ebx,[ebp+8]
|
||||
shl ebx,16
|
||||
mov bx,[ebp+16]
|
||||
mov ecx,[ebp+12]
|
||||
shl ecx,16
|
||||
mov cx,[ebp+20]
|
||||
mov edx,[ebp+28]
|
||||
shl edx,24
|
||||
add edx,[ebp+24]
|
||||
mov esi,[ebp+36]
|
||||
shl esi,24
|
||||
add esi,[ebp+32]
|
||||
mov edi,[ebp+40]
|
||||
xor eax,eax
|
||||
int 0x40
|
||||
pop edi esi ebx
|
||||
pop ebp
|
||||
ret 36
|
33
programs/develop/metcc/trunk/libc/mesys/event.asm
Normal file
33
programs/develop/metcc/trunk/libc/mesys/event.asm
Normal file
@ -0,0 +1,33 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_wait_for_event_infinite
|
||||
_msys_wait_for_event_infinite:
|
||||
mov eax,10
|
||||
int 0x40
|
||||
ret
|
||||
|
||||
public _msys_check_for_event
|
||||
_msys_check_for_event:
|
||||
mov eax,11
|
||||
int 0x40
|
||||
ret
|
||||
|
||||
public _msys_wait_for_event
|
||||
_msys_wait_for_event:
|
||||
;arg1 - time
|
||||
mov edx,ebx
|
||||
mov eax,23
|
||||
mov ebx,[esp+4]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 4
|
||||
|
||||
public _msys_set_wanted_events
|
||||
_msys_set_wanted_events:
|
||||
;arg1 - flags
|
||||
mov edx,ebx
|
||||
mov eax,40
|
||||
mov ebx,[esp+4]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 4
|
8
programs/develop/metcc/trunk/libc/mesys/exit.asm
Normal file
8
programs/develop/metcc/trunk/libc/mesys/exit.asm
Normal file
@ -0,0 +1,8 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_exit
|
||||
_msys_exit:
|
||||
xor eax,eax
|
||||
dec eax
|
||||
int 0x40
|
||||
; ret
|
110
programs/develop/metcc/trunk/libc/mesys/file_58.asm
Normal file
110
programs/develop/metcc/trunk/libc/mesys/file_58.asm
Normal file
@ -0,0 +1,110 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_read_file
|
||||
_msys_read_file:
|
||||
;arg1 - file name
|
||||
;arg2 - file offset
|
||||
;arg3 - size to read
|
||||
;arg4 - data
|
||||
;arg5 - file size
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
xor eax,eax
|
||||
mov [file_struct.operation],eax
|
||||
mov eax,[ebp+12]
|
||||
mov [file_struct.offset],eax
|
||||
mov eax,[ebp+16]
|
||||
mov [file_struct.offset],eax
|
||||
mov eax,[ebp+20]
|
||||
mov [file_struct.offset],eax
|
||||
mov [file_struct.temp_buffer],temp_buffer
|
||||
mov edx,[ebp+8]
|
||||
call copy_file_name
|
||||
push ebx
|
||||
mov ebx,file_struct
|
||||
mov eax,58
|
||||
int 0x40
|
||||
mov ecx,[ebp+24]
|
||||
test ecx,ecx
|
||||
jz .no_file_size
|
||||
mov [ecx],ebx
|
||||
.no_file_size:
|
||||
pop ebx
|
||||
pop ebp
|
||||
ret 20
|
||||
|
||||
copy_file_name:
|
||||
push esi edi
|
||||
cld
|
||||
mov edi,edx
|
||||
xor eax,eax
|
||||
xor ecx,ecx
|
||||
dec ecx
|
||||
repnz scasb
|
||||
not ecx
|
||||
mov edi,file_struct.path
|
||||
mov esi,edx
|
||||
rep movsb
|
||||
pop edi esi
|
||||
ret
|
||||
|
||||
public _msys_write_file
|
||||
_msys_write_file:
|
||||
;arg1 - file name
|
||||
;arg2 - size
|
||||
;arg3 - data
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
xor eax,eax
|
||||
mov [file_struct.offset],eax
|
||||
inc eax
|
||||
mov [file_struct.operation],eax
|
||||
mov eax,[ebp+12]
|
||||
mov [file_struct.size],eax
|
||||
mov eax,[ebp+16]
|
||||
mov [file_struct.data],eax
|
||||
mov [file_struct.temp_buffer],temp_buffer
|
||||
mov edx,[ebp+8]
|
||||
call copy_file_name
|
||||
push ebx
|
||||
mov eax,58
|
||||
mov ebx,file_struct
|
||||
int 0x40
|
||||
pop ebx
|
||||
pop ebp
|
||||
ret 12
|
||||
|
||||
public _msys_run_program
|
||||
_msys_run_program:
|
||||
;arg1 - program name
|
||||
;arg2 - parameters
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
mov [file_struct.operation],16
|
||||
xor eax,eax
|
||||
mov [file_struct.offset],eax
|
||||
mov [file_struct.data],eax
|
||||
mov eax,[ebp+12]
|
||||
mov [file_struct.param],eax
|
||||
mov [file_struct.temp_buffer],temp_buffer;
|
||||
mov edx,[ebp+8]
|
||||
call copy_file_name
|
||||
push ebx
|
||||
mov eax,58
|
||||
mov ebx,file_struct
|
||||
int 0x40
|
||||
pop ebx
|
||||
pop ebp
|
||||
ret 8
|
||||
section '.bss' writeable
|
||||
file_struct:
|
||||
.operation rd 1
|
||||
.offset rd 1
|
||||
.param:
|
||||
.size rd 1
|
||||
.data rd 1
|
||||
.temp_buffer rd 1
|
||||
.path rb 1024
|
||||
temp_buffer rb 4096
|
||||
|
||||
|
29
programs/develop/metcc/trunk/libc/mesys/ipc.asm
Normal file
29
programs/develop/metcc/trunk/libc/mesys/ipc.asm
Normal file
@ -0,0 +1,29 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_send_message
|
||||
_msys_send_message:
|
||||
;arg1 - pid
|
||||
;arg2 - msg
|
||||
;arg3 - size
|
||||
push ebx esi
|
||||
mov eax,60
|
||||
mov ebx,2
|
||||
mov ecx,[esp+12]
|
||||
mov edx,[esp+16]
|
||||
mov esi,[esp+20]
|
||||
int 0x40
|
||||
pop esi ebx
|
||||
ret 12
|
||||
|
||||
public _msys_define_receive_area
|
||||
_msys_define_receive_area:
|
||||
;arg1 - area
|
||||
;arg2 - size
|
||||
push ebx
|
||||
mov eax,60
|
||||
mov ebx,1
|
||||
mov ecx,[esp+8]
|
||||
mov edx,[esp+12]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 8
|
127
programs/develop/metcc/trunk/libc/mesys/irq.asm
Normal file
127
programs/develop/metcc/trunk/libc/mesys/irq.asm
Normal file
@ -0,0 +1,127 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_get_irq_owner
|
||||
_msys_get_irq_owner:
|
||||
;arg1 - irq
|
||||
mov edx,ebx
|
||||
mov eax,41
|
||||
mov ebx,[esp+4]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 4
|
||||
|
||||
public _msys_get_data_read_by_irq
|
||||
_msys_get_data_read_by_irq:
|
||||
;arg1 - irq
|
||||
;arg2 - *size
|
||||
;arg3 - data
|
||||
mov edx,ebx
|
||||
mov eax,42
|
||||
mov ebx,[esp+4]
|
||||
int 0x40
|
||||
cmp ecx,2
|
||||
jz .not_an_owner
|
||||
push ecx
|
||||
mov ecx,[esp+16]
|
||||
test ecx,ecx
|
||||
jz .ignore_data
|
||||
mov [ecx],bl
|
||||
.ignore_data:
|
||||
mov ecx,[esp+12]
|
||||
mov [ecx],eax
|
||||
pop eax
|
||||
mov ebx,edx
|
||||
ret 12
|
||||
.not_an_owner:
|
||||
mov eax,2
|
||||
mov ebx,edx
|
||||
ret
|
||||
|
||||
public _msys_send_data_to_device
|
||||
_msys_send_data_to_device:
|
||||
;arg1 - port
|
||||
;arg2 - data
|
||||
mov edx,ebx
|
||||
mov eax,63
|
||||
mov ebx,[esp+8]
|
||||
mov ecx,[esp+4]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 8
|
||||
|
||||
public _msys_receive_data_from_device
|
||||
_msys_receive_data_from_device:
|
||||
;arg1 - port
|
||||
;arg2 - data
|
||||
mov edx,ebx
|
||||
mov eax,43
|
||||
mov ecx,[esp+4]
|
||||
add ecx,0x80000000
|
||||
int 0x40
|
||||
mov ecx,[esp+8]
|
||||
mov [ecx],bl
|
||||
mov ebx,edx
|
||||
ret 8
|
||||
|
||||
public _msys_program_irq
|
||||
_msys_program_irq:
|
||||
;arg1 - intrtable
|
||||
;arg2 - irq
|
||||
mov edx,ebx
|
||||
mov eax,44
|
||||
mov ebx,[esp+4]
|
||||
mov ecx,[esp+8]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 8
|
||||
|
||||
public _msys_reserve_irq
|
||||
_msys_reserve_irq:
|
||||
;arg1 - irq
|
||||
mov edx,ebx
|
||||
mov eax,45
|
||||
xor ebx,ebx
|
||||
mov ecx,[esp+4]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 4
|
||||
|
||||
public _msys_free_irq
|
||||
_msys_free_irq:
|
||||
;arg1 - irq
|
||||
mov edx,ebx
|
||||
mov eax,45
|
||||
xor ebx,ebx
|
||||
inc ebx
|
||||
mov ecx,[esp+4]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 4
|
||||
|
||||
public _msys_reserve_port_area
|
||||
_msys_reserve_port_area:
|
||||
;arg1 - start
|
||||
;arg2 - end
|
||||
push ebx
|
||||
mov eax,46
|
||||
xor ebx,ebx
|
||||
mov ecx,[esp+8]
|
||||
mov edx,[esp+12]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 8
|
||||
|
||||
public _msys_free_port_area
|
||||
_msys_free_port_area:
|
||||
;arg1 - start
|
||||
;arg2 - end
|
||||
push ebx
|
||||
mov eax,46
|
||||
xor ebx,ebx
|
||||
inc ebx
|
||||
mov ecx,[esp+8]
|
||||
mov edx,[esp+12]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 8
|
||||
|
18
programs/develop/metcc/trunk/libc/mesys/keyboard.asm
Normal file
18
programs/develop/metcc/trunk/libc/mesys/keyboard.asm
Normal file
@ -0,0 +1,18 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_get_key
|
||||
_msys_get_key:
|
||||
mov eax,2
|
||||
int 0x40
|
||||
ret
|
||||
|
||||
public _msys_set_keyboard_mode
|
||||
_msys_set_keyboard_mode:
|
||||
;arg1 - mode
|
||||
mov edx,ebx
|
||||
mov eax,66
|
||||
xor ebx,ebx
|
||||
inc ebx
|
||||
mov ecx,[esp+4]
|
||||
mov ebx,edx
|
||||
ret 4
|
21
programs/develop/metcc/trunk/libc/mesys/line.asm
Normal file
21
programs/develop/metcc/trunk/libc/mesys/line.asm
Normal file
@ -0,0 +1,21 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_line
|
||||
_msys_line:
|
||||
;arg1 - x1
|
||||
;arg2 - y1
|
||||
;arg3 - x2
|
||||
;arg4 - y2
|
||||
;arg5 - color
|
||||
push ebx
|
||||
mov ebx,[esp+8]
|
||||
shl ebx,16
|
||||
mov bx,[esp+16]
|
||||
mov ecx,[esp+12]
|
||||
shl ecx,16
|
||||
mov cx,[esp+20]
|
||||
mov edx,[esp+24]
|
||||
mov eax,38
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 20
|
22
programs/develop/metcc/trunk/libc/mesys/midi.asm
Normal file
22
programs/develop/metcc/trunk/libc/mesys/midi.asm
Normal file
@ -0,0 +1,22 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_midi_reset
|
||||
_msys_midi_reset:
|
||||
mov edx,ebx
|
||||
mov eax,20
|
||||
xor ebx,ebx
|
||||
inc ebx
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret
|
||||
|
||||
public _msys_midi_send
|
||||
_msys_midi_send:
|
||||
;arg1 - data
|
||||
mov edx,ebx
|
||||
mov eax,20
|
||||
mov ebx,2
|
||||
xor ecx,ecx
|
||||
mov cl,[esp+4]
|
||||
mov ebx,edx
|
||||
ret 4
|
146
programs/develop/metcc/trunk/libc/mesys/pci.asm
Normal file
146
programs/develop/metcc/trunk/libc/mesys/pci.asm
Normal file
@ -0,0 +1,146 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_get_pci_version
|
||||
_msys_get_pci_version:
|
||||
mov edx,ebx
|
||||
mov eax,62
|
||||
xor ebx,ebx
|
||||
int 0x40
|
||||
movzx eax,ax
|
||||
mov ebx,edx
|
||||
ret
|
||||
|
||||
public _msys_get_last_pci_bus
|
||||
_msys_get_last_pci_bus:
|
||||
mov edx,ebx
|
||||
mov eax,62
|
||||
xor ebx,ebx
|
||||
inc ebx
|
||||
int 0x40
|
||||
movzx eax,al
|
||||
mov ebx,edx
|
||||
ret
|
||||
|
||||
public _msys_get_pci_access_mechanism
|
||||
_msys_get_pci_access_mechanism:
|
||||
mov edx,ebx
|
||||
mov eax,62
|
||||
mov ebx,2
|
||||
int 0x40
|
||||
movzx eax,al
|
||||
mov ebx,edx
|
||||
ret
|
||||
|
||||
public _msys_pci_read_config_byte
|
||||
_msys_pci_read_config_byte:
|
||||
;arg1 - bus
|
||||
;arg2 - dev
|
||||
;arg3 - fn
|
||||
;arg4 - reg
|
||||
mov edx,ebx
|
||||
mov eax,62
|
||||
mov bl,4
|
||||
mov bh,[esp+4]
|
||||
mov ch,[esp+8]
|
||||
shl ch,3
|
||||
add ch,[esp+12]
|
||||
mov cl,[esp+16]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 16
|
||||
|
||||
public _msys_pci_read_config_word
|
||||
_msys_pci_read_config_word:
|
||||
;arg1 - bus
|
||||
;arg2 - dev
|
||||
;arg3 - fn
|
||||
;arg4 - reg
|
||||
mov edx,ebx
|
||||
mov eax,62
|
||||
mov bl,5
|
||||
mov bh,[esp+4]
|
||||
mov ch,[esp+8]
|
||||
shl ch,3
|
||||
add ch,[esp+12]
|
||||
mov cl,[esp+16]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 16
|
||||
|
||||
public _msys_pci_read_config_dword
|
||||
_msys_pci_read_config_dword:
|
||||
;arg1 - bus
|
||||
;arg2 - dev
|
||||
;arg3 - fn
|
||||
;arg4 - reg
|
||||
mov edx,ebx
|
||||
mov eax,62
|
||||
mov bl,6
|
||||
mov bh,[esp+4]
|
||||
mov ch,[esp+8]
|
||||
shl ch,3
|
||||
add ch,[esp+12]
|
||||
mov cl,[esp+16]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 16
|
||||
|
||||
public _msys_pci_write_config_byte
|
||||
_msys_pci_write_config_byte:
|
||||
;arg1 - bus
|
||||
;arg2 - dev
|
||||
;arg3 - fn
|
||||
;arg4 - reg
|
||||
;arg5 - value
|
||||
push ebx
|
||||
mov eax,62
|
||||
mov bl,8
|
||||
mov bh,[esp+8]
|
||||
mov ch,[esp+12]
|
||||
shl ch,3
|
||||
mov ch,[esp+16]
|
||||
mov cl,[esp+20]
|
||||
movzx edx,byte [esp+24]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 20
|
||||
|
||||
public _msys_pci_write_config_word
|
||||
_msys_pci_write_config_word:
|
||||
;arg1 - bus
|
||||
;arg2 - dev
|
||||
;arg3 - fn
|
||||
;arg4 - reg
|
||||
;arg5 - value
|
||||
push ebx
|
||||
mov eax,62
|
||||
mov bl,9
|
||||
mov bh,[esp+8]
|
||||
mov ch,[esp+12]
|
||||
shl ch,3
|
||||
mov ch,[esp+16]
|
||||
mov cl,[esp+20]
|
||||
movzx edx,word [esp+24]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 20
|
||||
|
||||
public _msys_pci_write_config_dword
|
||||
_msys_pci_write_config_dword:
|
||||
;arg1 - bus
|
||||
;arg2 - dev
|
||||
;arg3 - fn
|
||||
;arg4 - reg
|
||||
;arg5 - value
|
||||
push ebx
|
||||
mov eax,62
|
||||
mov bl,10
|
||||
mov bh,[esp+8]
|
||||
mov ch,[esp+12]
|
||||
shl ch,3
|
||||
mov ch,[esp+16]
|
||||
mov cl,[esp+20]
|
||||
mov edx,[esp+24]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 20
|
16
programs/develop/metcc/trunk/libc/mesys/pixel.asm
Normal file
16
programs/develop/metcc/trunk/libc/mesys/pixel.asm
Normal file
@ -0,0 +1,16 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_putpixel
|
||||
_msys_putpixel:
|
||||
;arg1 - x
|
||||
;arg2 - y
|
||||
;arg3 - color
|
||||
push ebx
|
||||
xor eax,eax
|
||||
mov ebx,[esp+8]
|
||||
inc eax
|
||||
mov ecx,[esp+12]
|
||||
mov edx,[esp+16]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 12
|
13
programs/develop/metcc/trunk/libc/mesys/process.asm
Normal file
13
programs/develop/metcc/trunk/libc/mesys/process.asm
Normal file
@ -0,0 +1,13 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_get_process_table
|
||||
_msys_get_process_table:
|
||||
;arg1 - pointer to information
|
||||
;arg2 - pid
|
||||
mov edx,ebx
|
||||
mov eax,9
|
||||
mov ebx,[esp+4]
|
||||
mov ecx,[esp+8]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 8
|
15
programs/develop/metcc/trunk/libc/mesys/screen.asm
Normal file
15
programs/develop/metcc/trunk/libc/mesys/screen.asm
Normal file
@ -0,0 +1,15 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_get_screen_size
|
||||
_msys_get_screen_size:
|
||||
;arg1 - x
|
||||
;arg2 - y
|
||||
mov eax,14
|
||||
int 0x40
|
||||
mov ecx,[esp+8]
|
||||
mov [ecx],ax
|
||||
mov word [ecx+2],0
|
||||
shr eax,16
|
||||
mov ecx,[esp+4]
|
||||
mov [ecx],eax
|
||||
ret 8
|
70
programs/develop/metcc/trunk/libc/mesys/sound.asm
Normal file
70
programs/develop/metcc/trunk/libc/mesys/sound.asm
Normal file
@ -0,0 +1,70 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_sound_load_block
|
||||
_msys_sound_load_block:
|
||||
;arg1 - blockptr
|
||||
mov edx,ebx
|
||||
mov eax,55
|
||||
xor ebx,ebx
|
||||
mov ecx,[esp+4]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 4
|
||||
|
||||
public _msys_sound_play_block
|
||||
_msys_sound_play_block:
|
||||
mov edx,ebx
|
||||
mov eax,55
|
||||
xor ebx,ebx
|
||||
inc ebx
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret
|
||||
|
||||
public _msys_sound_set_channels
|
||||
_msys_sound_set_channels:
|
||||
;arg1 - channels
|
||||
push ebx
|
||||
mov eax,55
|
||||
mov ebx,2
|
||||
xor ecx,ecx
|
||||
mov edx,[esp+8]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 4
|
||||
|
||||
public _msys_sound_set_data_size
|
||||
_msys_sound_set_data_size:
|
||||
;arg1 - data size
|
||||
push ebx
|
||||
mov eax,55
|
||||
mov ebx,2
|
||||
xor ecx,ecx
|
||||
inc ecx
|
||||
mov edx,[esp+8]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 4
|
||||
|
||||
public _msys_sound_set_frequency
|
||||
_msys_sound_set_frequency:
|
||||
;arg1 - frequency
|
||||
push ebx
|
||||
mov eax,55
|
||||
mov ebx,2
|
||||
mov ecx,2
|
||||
mov edx,[esp+8]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret 4
|
||||
|
||||
public _msys_sound_speaker_play
|
||||
_msys_sound_speaker_play:
|
||||
;arg1 - data
|
||||
mov edx,ebx
|
||||
mov eax,55
|
||||
mov ebx,55
|
||||
mov ecx,[esp+4]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 4
|
33
programs/develop/metcc/trunk/libc/mesys/thread.asm
Normal file
33
programs/develop/metcc/trunk/libc/mesys/thread.asm
Normal file
@ -0,0 +1,33 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
extrn malloc
|
||||
public _msys_start_thread
|
||||
_msys_start_thread:
|
||||
;arg1 - proc
|
||||
;arg2 - stacksize
|
||||
;arg3 - pid
|
||||
push dword [esp+8]
|
||||
call malloc
|
||||
test eax,eax
|
||||
jz .no_mem
|
||||
push ebx
|
||||
mov edx,eax
|
||||
add edx,[esp+12]
|
||||
mov [edx-4],dword 0
|
||||
mov ecx,[esp+8]
|
||||
mov ebx,1
|
||||
mov eax,51
|
||||
int 0x40
|
||||
mov ebx,[esp+16]
|
||||
test ebx,ebx
|
||||
jz .no_val
|
||||
mov [ebx],eax
|
||||
.no_val:
|
||||
mov eax,edx
|
||||
sub eax,[esp+12]
|
||||
pop ebx
|
||||
ret 12
|
||||
.no_mem:
|
||||
mov ecx,[esp+12]
|
||||
mov [ecx],eax
|
||||
ret 12
|
11
programs/develop/metcc/trunk/libc/mesys/window_redraw.asm
Normal file
11
programs/develop/metcc/trunk/libc/mesys/window_redraw.asm
Normal file
@ -0,0 +1,11 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_window_redraw
|
||||
_msys_window_redraw:
|
||||
;arg1 - status
|
||||
mov edx,ebx
|
||||
mov eax,12
|
||||
mov ebx,[esp+4]
|
||||
int 0x40
|
||||
mov ebx,edx
|
||||
ret 4
|
20
programs/develop/metcc/trunk/libc/mesys/write_text.asm
Normal file
20
programs/develop/metcc/trunk/libc/mesys/write_text.asm
Normal file
@ -0,0 +1,20 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public _msys_write_text
|
||||
_msys_write_text:
|
||||
;arg1 - x
|
||||
;arg2 - y
|
||||
;arg3 - color
|
||||
;arg4 - text
|
||||
;arg5 - len
|
||||
push ebx esi
|
||||
mov eax,4
|
||||
mov ebx,[esp+12]
|
||||
shl ebx,16
|
||||
mov bx,[esp+16]
|
||||
mov ecx,[esp+20]
|
||||
mov edx,[esp+24]
|
||||
mov esi,[esp+28]
|
||||
int 0x40
|
||||
pop esi ebx
|
||||
ret 20
|
130
programs/develop/metcc/trunk/libc/start/start.asm
Normal file
130
programs/develop/metcc/trunk/libc/start/start.asm
Normal file
@ -0,0 +1,130 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public start
|
||||
extrn mf_init
|
||||
extrn main
|
||||
;include 'debug2.inc'
|
||||
__DEBUG__=0
|
||||
virtual at 0
|
||||
db 'MENUET01' ; 1. Magic number (8 bytes)
|
||||
dd 0x01 ; 2. Version of executable file
|
||||
dd 0x0 ; 3. Start address
|
||||
dd 0x0 ; 4. Size of image
|
||||
dd 0x100000 ; 5. Size of needed memory
|
||||
dd 0x100000 ; 6. Pointer to stack
|
||||
hparams dd 0x0 ; 7. Pointer to program arguments
|
||||
hpath dd 0x0 ; 8. Pointer to program path
|
||||
end virtual
|
||||
start:
|
||||
;DEBUGF 'Start programm\n'
|
||||
xor eax,eax
|
||||
call mf_init
|
||||
;DEBUGF ' path "%s"\n params "%s"\n', .path, .params
|
||||
; check for overflow
|
||||
mov al, [path+buf_len-1]
|
||||
or al, [params+buf_len-1]
|
||||
jnz .crash
|
||||
; check if path written by OS
|
||||
mov eax, [hparams]
|
||||
test eax, eax
|
||||
jz .without_path
|
||||
mov eax, path
|
||||
.without_path:
|
||||
mov esi, eax
|
||||
call push_param
|
||||
; retrieving parameters
|
||||
mov esi, params
|
||||
xor edx, edx ; dl - èä¸ò ïàðàìåòð(1) èëè ðàçäåëèòåëè(0)
|
||||
; dh - ñèìâîë ñ êîòîðîãî íà÷àëñÿ ïàðàìåòð (1 êàâû÷êè, 0 îñòàëüíîå)
|
||||
mov ecx, 1 ; cl = 1
|
||||
; ch = 0 ïðîñòî íîëü
|
||||
.parse:
|
||||
lodsb
|
||||
test al, al
|
||||
jz .run
|
||||
test dl, dl
|
||||
jnz .findendparam
|
||||
;{åñëè áûë ðàçäåëèòåëü
|
||||
cmp al, ' '
|
||||
jz .parse ;çàãðóæåí ïðîáåë, ãðóçèì ñëåäóþùèé ñèìâîë
|
||||
mov dl, cl ;íà÷èíàåòñÿ ïàðàìåòð
|
||||
cmp al, '"'
|
||||
jz @f ;çàãðóæåíû êàâû÷êè
|
||||
mov dh, ch ;ïàðàìåòð áåç êàâû÷åê
|
||||
dec esi
|
||||
call push_param
|
||||
inc esi
|
||||
jmp .parse
|
||||
|
||||
@@:
|
||||
mov dh, cl ;ïàðàìåòð â êàâû÷åêàõ
|
||||
call push_param ;åñëè íå ïðîáåë çíà÷èò íà÷èíàåòñÿ êàêîé òî ïàðàìåòð
|
||||
jmp .parse ;åñëè áûë ðàçäåëèòåëü}
|
||||
|
||||
.findendparam:
|
||||
test dh, dh
|
||||
jz @f ; áåç êàâû÷åê
|
||||
cmp al, '"'
|
||||
jz .clear
|
||||
jmp .parse
|
||||
@@:
|
||||
cmp al, ' '
|
||||
jnz .parse
|
||||
|
||||
.clear:
|
||||
lea ebx, [esi - 1]
|
||||
mov [ebx], ch
|
||||
mov dl, ch
|
||||
jmp .parse
|
||||
|
||||
.run:
|
||||
;DEBUGF 'call main(%x, %x) with params:\n', [argc], argv
|
||||
if __DEBUG__ = 1
|
||||
mov ecx, [argc]
|
||||
@@:
|
||||
lea esi, [ecx * 4 + argv-4]
|
||||
DEBUGF '0x%x) "%s"\n', cx, [esi]
|
||||
loop @b
|
||||
end if
|
||||
push [argc]
|
||||
push argv
|
||||
call main
|
||||
.exit:
|
||||
;DEBUGF 'Exit from prog\n';
|
||||
xor eax,eax
|
||||
dec eax
|
||||
int 0x40
|
||||
dd -1
|
||||
.crash:
|
||||
;DEBUGF 'E:buffer overflowed\n'
|
||||
jmp .exit
|
||||
;============================
|
||||
push_param:
|
||||
;============================
|
||||
;parameters
|
||||
; esi - pointer
|
||||
;description
|
||||
; procedure increase argc
|
||||
; and add pointer to array argv
|
||||
; procedure changes ebx
|
||||
mov ebx, [argc]
|
||||
cmp ebx, max_parameters
|
||||
jae .dont_add
|
||||
mov [argv+4*ebx], esi
|
||||
inc [argc]
|
||||
.dont_add:
|
||||
ret
|
||||
;==============================
|
||||
public params as '__argv'
|
||||
public path as '__path'
|
||||
|
||||
section '.bss'
|
||||
buf_len = 0x400
|
||||
max_parameters=0x20
|
||||
argc rd 1
|
||||
argv rd max_parameters
|
||||
path rb buf_len
|
||||
params rb buf_len
|
||||
|
||||
;section '.data'
|
||||
;include_debug_strings ; ALWAYS present in data section
|
156
programs/develop/metcc/trunk/libc/string/_mesys.asm
Normal file
156
programs/develop/metcc/trunk/libc/string/_mesys.asm
Normal file
@ -0,0 +1,156 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
|
||||
public _msys_draw_window
|
||||
_msys_draw_window:
|
||||
;arg1 - xcoord
|
||||
;arg2 - ycoord
|
||||
;arg3 - xsize
|
||||
;arg4 - ysize
|
||||
;arg5 - workcolor
|
||||
;arg6 - type
|
||||
;arg7 - captioncolor
|
||||
;arg8 - windowtype
|
||||
;arg9 - bordercolor
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
push ebx esi edi
|
||||
mov ebx,[ebp+8]
|
||||
shl ebx,16
|
||||
mov bx,[ebp+16]
|
||||
mov ecx,[ebp+12]
|
||||
shl ecx,16
|
||||
mov cx,[ebp+20]
|
||||
mov edx,[ebp+28]
|
||||
shl edx,24
|
||||
add edx,[ebp+24]
|
||||
mov esi,[ebp+36]
|
||||
shl esi,24
|
||||
add esi,[ebp+32]
|
||||
mov edi,[ebp+40]
|
||||
xor eax,eax
|
||||
int 0x40
|
||||
pop edi esi ebx
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
public _msys_read_file
|
||||
_msys_read_file:
|
||||
;arg1 - file name
|
||||
;arg2 - file offset
|
||||
;arg3 - size to read
|
||||
;arg4 - data
|
||||
;arg5 - temp buffer
|
||||
;arg6 - file size
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
xor eax,eax
|
||||
mov [file_struct.operation],eax
|
||||
mov eax,[ebp+12]
|
||||
mov [file_struct.offset],eax
|
||||
mov eax,[ebp+16]
|
||||
mov [file_struct.offset],eax
|
||||
mov eax,[ebp+20]
|
||||
mov [file_struct.offset],eax
|
||||
mov [file_struct.temp_buffer],temp_buffer
|
||||
mov edx,[ebp+8]
|
||||
call copy_file_name
|
||||
push ebx
|
||||
mov ebx,file_struct
|
||||
mov eax,58
|
||||
int 0x40
|
||||
mov ecx,[ebp+28]
|
||||
test ecx,ecx
|
||||
jz .no_file_size
|
||||
mov [ecx],ebx
|
||||
.no_file_size:
|
||||
pop ebx
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
copy_file_name:
|
||||
push esi edi
|
||||
cld
|
||||
mov edi,edx
|
||||
xor eax,eax
|
||||
xor ecx,ecx
|
||||
dec ecx
|
||||
repnz scasb
|
||||
not ecx
|
||||
mov edi,file_struct.path
|
||||
mov esi,edx
|
||||
rep movsb
|
||||
pop edi esi
|
||||
ret
|
||||
|
||||
public _msys_write_file
|
||||
_msys_write_file:
|
||||
;arg1 - file name
|
||||
;arg2 - size
|
||||
;arg3 - data
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
xor eax,eax
|
||||
mov [file_struct.offset],eax
|
||||
inc eax
|
||||
mov [file_struct.operation],eax
|
||||
mov eax,[ebp+12]
|
||||
mov [file_struct.size],eax
|
||||
mov eax,[ebp+16]
|
||||
mov [file_struct.data],eax
|
||||
mov [file_struct.temp_buffer],temp_buffer
|
||||
mov edx,[ebp+8]
|
||||
call copy_file_name
|
||||
push ebx
|
||||
mov eax,58
|
||||
mov ebx,file_struct
|
||||
int 0x40
|
||||
pop ebx
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
public _msys_run_program
|
||||
_msys_run_program:
|
||||
;arg1 - program name
|
||||
;arg2 - parameters
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
mov [file_struct.operation],16
|
||||
xor eax,eax
|
||||
mov [file_struct.offset],eax
|
||||
mov [file_struct.data],eax
|
||||
mov eax,[ebp+12]
|
||||
mov [file_struct.param],eax
|
||||
mov [file_struct.temp_buffer],temp_buffer;
|
||||
mov edx,[ebp+8]
|
||||
call copy_file_name
|
||||
push ebx
|
||||
mov eax,58
|
||||
mov ebx,file_struct
|
||||
int 0x40
|
||||
pop ebx
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
public _msys_debug_out
|
||||
_msys_debug_out:
|
||||
;arg1 - char to out
|
||||
push ebx
|
||||
mov ecx,[esp+8]
|
||||
mov ebx,1
|
||||
mov eax,63
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret
|
||||
section '.data' writeable
|
||||
section '.bss' writeable
|
||||
file_struct:
|
||||
.operation rd 1
|
||||
.offset rd 1
|
||||
.param:
|
||||
.size rd 1
|
||||
.data rd 1
|
||||
.temp_buffer rd 1
|
||||
.path rb 1024
|
||||
temp_buffer rb 4096
|
||||
|
10
programs/develop/metcc/trunk/libc/string/memchr.c
Normal file
10
programs/develop/metcc/trunk/libc/string/memchr.c
Normal file
@ -0,0 +1,10 @@
|
||||
void* memchr(const void* buf,int c,int count)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<count;i++)
|
||||
if (*(char*)buf==c)
|
||||
return (void*)buf;
|
||||
else
|
||||
buf++;
|
||||
return (void*)0;
|
||||
}
|
13
programs/develop/metcc/trunk/libc/string/memcmp.c
Normal file
13
programs/develop/metcc/trunk/libc/string/memcmp.c
Normal file
@ -0,0 +1,13 @@
|
||||
typedef unsigned char uc;
|
||||
int memcmp(const void* buf1,const void* buf2,int count)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<count;i++)
|
||||
{
|
||||
if (*(uc*)buf1<*(uc*)buf2)
|
||||
return -1;
|
||||
if (*(uc*)buf1>*(uc*)buf2)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
16
programs/develop/metcc/trunk/libc/string/memmove.asm
Normal file
16
programs/develop/metcc/trunk/libc/string/memmove.asm
Normal file
@ -0,0 +1,16 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public memcpy
|
||||
public memmove
|
||||
memcpy:
|
||||
memmove:
|
||||
push esi edi
|
||||
mov edi,[esp+12]
|
||||
mov esi,[esp+16]
|
||||
mov ecx,[esp+20]
|
||||
jecxz .no_copy
|
||||
cld
|
||||
rep movsb
|
||||
.no_copy:
|
||||
pop edi esi
|
||||
ret
|
15
programs/develop/metcc/trunk/libc/string/memset.asm
Normal file
15
programs/develop/metcc/trunk/libc/string/memset.asm
Normal file
@ -0,0 +1,15 @@
|
||||
format ELF
|
||||
section '.text' executable
|
||||
public memset
|
||||
memset:
|
||||
push edi
|
||||
mov edi,[esp+8]
|
||||
mov eax,[esp+12]
|
||||
mov ecx,[esp+16]
|
||||
jecxz .no_set
|
||||
cld
|
||||
rep stosb
|
||||
.no_set:
|
||||
pop edi
|
||||
ret
|
||||
|
13
programs/develop/metcc/trunk/libc/string/strcat.c
Normal file
13
programs/develop/metcc/trunk/libc/string/strcat.c
Normal file
@ -0,0 +1,13 @@
|
||||
char* strcat(char* strDest, const char* strSource)
|
||||
{
|
||||
char* res;
|
||||
res=strDest;
|
||||
while (*strDest!='\0') strDest++;
|
||||
while (*strSource!='\0')
|
||||
{
|
||||
*strDest=*strSource;
|
||||
strDest++;
|
||||
strSource++;
|
||||
}
|
||||
return res;
|
||||
}
|
10
programs/develop/metcc/trunk/libc/string/strchr.c
Normal file
10
programs/develop/metcc/trunk/libc/string/strchr.c
Normal file
@ -0,0 +1,10 @@
|
||||
char* strchr(const char* string, int c)
|
||||
{
|
||||
while (*string!='\0')
|
||||
{
|
||||
if (*string==c)
|
||||
return (char*)string;
|
||||
string++;
|
||||
}
|
||||
return (char*)0;
|
||||
}
|
14
programs/develop/metcc/trunk/libc/string/strcmp.c
Normal file
14
programs/develop/metcc/trunk/libc/string/strcmp.c
Normal file
@ -0,0 +1,14 @@
|
||||
int strcmp(const char* string1, const char* string2)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (*string1<*string2)
|
||||
return -1;
|
||||
if (*string1>*string2)
|
||||
return 1;
|
||||
if (*string1=='\0')
|
||||
return 0;
|
||||
string1++;
|
||||
string2++;
|
||||
}
|
||||
}
|
4
programs/develop/metcc/trunk/libc/string/strcoll.c
Normal file
4
programs/develop/metcc/trunk/libc/string/strcoll.c
Normal file
@ -0,0 +1,4 @@
|
||||
int strcoll(const char* string1,const char* string2)
|
||||
{
|
||||
return strcmp(string1,string2);
|
||||
}
|
14
programs/develop/metcc/trunk/libc/string/strcpy.c
Normal file
14
programs/develop/metcc/trunk/libc/string/strcpy.c
Normal file
@ -0,0 +1,14 @@
|
||||
char* strcpy(char* strDest,char* strSource)
|
||||
{
|
||||
char* res;
|
||||
res=strDest;
|
||||
while(1)
|
||||
{
|
||||
*strDest=*strSource;
|
||||
if (*strSource=='\0')
|
||||
break;
|
||||
strDest++;
|
||||
strSource++;
|
||||
}
|
||||
return res;
|
||||
}
|
17
programs/develop/metcc/trunk/libc/string/strcspn.c
Normal file
17
programs/develop/metcc/trunk/libc/string/strcspn.c
Normal file
@ -0,0 +1,17 @@
|
||||
int strcspn(const char* string, const char* strCharSet)
|
||||
{
|
||||
const char* temp;
|
||||
int i;
|
||||
i=0;
|
||||
while(1)
|
||||
{
|
||||
temp=strCharSet;
|
||||
while (*temp!='\0')
|
||||
{
|
||||
if (*string==*temp)
|
||||
return i;
|
||||
temp++;
|
||||
}
|
||||
i++;string++;
|
||||
}
|
||||
}
|
9
programs/develop/metcc/trunk/libc/string/strdup.c
Normal file
9
programs/develop/metcc/trunk/libc/string/strdup.c
Normal file
@ -0,0 +1,9 @@
|
||||
char* strdup(char* str)
|
||||
{
|
||||
char* res;
|
||||
int len;
|
||||
len=strlen(str)+1;
|
||||
res=malloc(len);
|
||||
memcpy(res,str,len);
|
||||
return res;
|
||||
}
|
4
programs/develop/metcc/trunk/libc/string/strerror.c
Normal file
4
programs/develop/metcc/trunk/libc/string/strerror.c
Normal file
@ -0,0 +1,4 @@
|
||||
char* strerror(int err)
|
||||
{
|
||||
return (char*)0;
|
||||
}
|
11
programs/develop/metcc/trunk/libc/string/strlen.c
Normal file
11
programs/develop/metcc/trunk/libc/string/strlen.c
Normal file
@ -0,0 +1,11 @@
|
||||
int strlen(const char* string)
|
||||
{
|
||||
int i;
|
||||
i=0;
|
||||
while (*string!='\0')
|
||||
{
|
||||
i++;
|
||||
string++;
|
||||
}
|
||||
return i;
|
||||
}
|
16
programs/develop/metcc/trunk/libc/string/strnbrk.c
Normal file
16
programs/develop/metcc/trunk/libc/string/strnbrk.c
Normal file
@ -0,0 +1,16 @@
|
||||
char* strpbrk(const char* string, const char* strCharSet)
|
||||
{
|
||||
char* temp;
|
||||
while (*string!='\0')
|
||||
{
|
||||
temp=strCharSet;
|
||||
while (*temp!='\0')
|
||||
{
|
||||
if (*string==*temp)
|
||||
return string;
|
||||
temp++;
|
||||
}
|
||||
string++;
|
||||
}
|
||||
return (char*)0;
|
||||
}
|
14
programs/develop/metcc/trunk/libc/string/strncat.c
Normal file
14
programs/develop/metcc/trunk/libc/string/strncat.c
Normal file
@ -0,0 +1,14 @@
|
||||
char* strncat(char* strDest,const char* strSource,int count)
|
||||
{
|
||||
char* res;
|
||||
res=strDest;
|
||||
while (*strDest!='\0') strDest++;
|
||||
while (count>0 && *strSource!='\0')
|
||||
{
|
||||
*strDest=*strSource;
|
||||
count--;
|
||||
strDest++;
|
||||
strSource++;
|
||||
}
|
||||
return res;
|
||||
}
|
14
programs/develop/metcc/trunk/libc/string/strncmp.c
Normal file
14
programs/develop/metcc/trunk/libc/string/strncmp.c
Normal file
@ -0,0 +1,14 @@
|
||||
int strncmp(const char* string1, const char* string2, int count)
|
||||
{
|
||||
while(count>0)
|
||||
{
|
||||
if (*string1<*string2)
|
||||
return -1;
|
||||
if (*string1>*string2)
|
||||
return 1;
|
||||
if (*string1=='\0')
|
||||
return 0;
|
||||
count--;
|
||||
}
|
||||
return 0;
|
||||
}
|
14
programs/develop/metcc/trunk/libc/string/strncpy.c
Normal file
14
programs/develop/metcc/trunk/libc/string/strncpy.c
Normal file
@ -0,0 +1,14 @@
|
||||
char* strncpy(char* strDest,const char* strSource,int count)
|
||||
{
|
||||
char* res;
|
||||
res=strDest;
|
||||
while (count>0)
|
||||
{
|
||||
*strDest=*strSource;
|
||||
if (*strSource!='\0')
|
||||
strSource++;
|
||||
strDest++;
|
||||
count--;
|
||||
}
|
||||
return res;
|
||||
}
|
14
programs/develop/metcc/trunk/libc/string/strrchr.c
Normal file
14
programs/develop/metcc/trunk/libc/string/strrchr.c
Normal file
@ -0,0 +1,14 @@
|
||||
char* strrchr(const char* s,int c)
|
||||
{
|
||||
char* res;
|
||||
res=(char*)0;
|
||||
while (1)
|
||||
{
|
||||
if (*s==(char)c)
|
||||
res=(char*)s;
|
||||
if (*s=='\0')
|
||||
break;
|
||||
s++;
|
||||
}
|
||||
return res;
|
||||
}
|
20
programs/develop/metcc/trunk/libc/string/strspn.c
Normal file
20
programs/develop/metcc/trunk/libc/string/strspn.c
Normal file
@ -0,0 +1,20 @@
|
||||
int strspn(const char* string,const char* strCharSet)
|
||||
{
|
||||
int i;
|
||||
const char* temp;
|
||||
i=0;
|
||||
while (*string!='\0')
|
||||
{
|
||||
temp=strCharSet;
|
||||
while (temp!='\0')
|
||||
{
|
||||
if (*temp==*string)
|
||||
break;
|
||||
}
|
||||
if (temp=='\0')
|
||||
break;
|
||||
*string++;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
13
programs/develop/metcc/trunk/libc/string/strstr.c
Normal file
13
programs/develop/metcc/trunk/libc/string/strstr.c
Normal file
@ -0,0 +1,13 @@
|
||||
extern int strncmp(char* s1,char* s2,int len);
|
||||
char* strstr(const char* s, const char* find)
|
||||
{
|
||||
int len;
|
||||
len=strlen(find);
|
||||
while (1)
|
||||
{
|
||||
if (strncmp(s,find,len)==0) return s;
|
||||
if (*s=='\0')
|
||||
return (char*) 0;
|
||||
s++;
|
||||
}
|
||||
}
|
14
programs/develop/metcc/trunk/libc/string/strtok.c
Normal file
14
programs/develop/metcc/trunk/libc/string/strtok.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include "string.h"
|
||||
char* strtok(char* s,const char* delim)
|
||||
{
|
||||
char* res;
|
||||
if (*s=='\0')
|
||||
return (char*)0;
|
||||
s+=strspn(s,delim);
|
||||
if (*s=='\0')
|
||||
return (char*)0;
|
||||
res=s;
|
||||
s+=strcspn(s,delim);
|
||||
*s=='\0';
|
||||
return res;
|
||||
}
|
4
programs/develop/metcc/trunk/libc/string/strxfrm.c
Normal file
4
programs/develop/metcc/trunk/libc/string/strxfrm.c
Normal file
@ -0,0 +1,4 @@
|
||||
int strxfrm(char* strDest, const char* strSource, int count)
|
||||
{
|
||||
return 0;
|
||||
}
|
4
programs/develop/metcc/trunk/readme.txt
Normal file
4
programs/develop/metcc/trunk/readme.txt
Normal file
@ -0,0 +1,4 @@
|
||||
The main file of metcc is "tcc.c". It certainly can be compiled by MinGW Studio.
|
||||
In order to compile MenuetOS program you must have start.o, metcc.exe in the same
|
||||
directory. The command line should be of type "metcc.exe program.c melibc.a -oprogram".
|
||||
In order to compile "melibc.a" you should configure paths is compile.js and run it.
|
504
programs/develop/metcc/trunk/source/COPYING
Normal file
504
programs/develop/metcc/trunk/source/COPYING
Normal file
@ -0,0 +1,504 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
1
programs/develop/metcc/trunk/source/VERSION
Normal file
1
programs/develop/metcc/trunk/source/VERSION
Normal file
@ -0,0 +1 @@
|
||||
0.9.23
|
1386
programs/develop/metcc/trunk/source/arm-gen.c
Normal file
1386
programs/develop/metcc/trunk/source/arm-gen.c
Normal file
File diff suppressed because it is too large
Load Diff
867
programs/develop/metcc/trunk/source/bcheck.c
Normal file
867
programs/develop/metcc/trunk/source/bcheck.c
Normal file
@ -0,0 +1,867 @@
|
||||
/*
|
||||
* Tiny C Memory and bounds checker
|
||||
*
|
||||
* Copyright (c) 2002 Fabrice Bellard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#ifndef __FreeBSD__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
//#define BOUND_DEBUG
|
||||
|
||||
/* define so that bound array is static (faster, but use memory if
|
||||
bound checking not used) */
|
||||
//#define BOUND_STATIC
|
||||
|
||||
/* use malloc hooks. Currently the code cannot be reliable if no hooks */
|
||||
#define CONFIG_TCC_MALLOC_HOOKS
|
||||
|
||||
#define HAVE_MEMALIGN
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__dietlibc__)
|
||||
#warning Bound checking not fully supported on FreeBSD
|
||||
#undef CONFIG_TCC_MALLOC_HOOKS
|
||||
#undef HAVE_MEMALIGN
|
||||
#endif
|
||||
|
||||
#define BOUND_T1_BITS 13
|
||||
#define BOUND_T2_BITS 11
|
||||
#define BOUND_T3_BITS (32 - BOUND_T1_BITS - BOUND_T2_BITS)
|
||||
|
||||
#define BOUND_T1_SIZE (1 << BOUND_T1_BITS)
|
||||
#define BOUND_T2_SIZE (1 << BOUND_T2_BITS)
|
||||
#define BOUND_T3_SIZE (1 << BOUND_T3_BITS)
|
||||
#define BOUND_E_BITS 4
|
||||
|
||||
#define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS)
|
||||
#define BOUND_T23_SIZE (1 << BOUND_T23_BITS)
|
||||
|
||||
|
||||
/* this pointer is generated when bound check is incorrect */
|
||||
#define INVALID_POINTER ((void *)(-2))
|
||||
/* size of an empty region */
|
||||
#define EMPTY_SIZE 0xffffffff
|
||||
/* size of an invalid region */
|
||||
#define INVALID_SIZE 0
|
||||
|
||||
typedef struct BoundEntry {
|
||||
unsigned long start;
|
||||
unsigned long size;
|
||||
struct BoundEntry *next;
|
||||
unsigned long is_invalid; /* true if pointers outside region are invalid */
|
||||
} BoundEntry;
|
||||
|
||||
/* external interface */
|
||||
void __bound_init(void);
|
||||
void __bound_new_region(void *p, unsigned long size);
|
||||
int __bound_delete_region(void *p);
|
||||
|
||||
#define FASTCALL __attribute__((regparm(3)))
|
||||
|
||||
void *__bound_malloc(size_t size, const void *caller);
|
||||
void *__bound_memalign(size_t size, size_t align, const void *caller);
|
||||
void __bound_free(void *ptr, const void *caller);
|
||||
void *__bound_realloc(void *ptr, size_t size, const void *caller);
|
||||
static void *libc_malloc(size_t size);
|
||||
static void libc_free(void *ptr);
|
||||
static void install_malloc_hooks(void);
|
||||
static void restore_malloc_hooks(void);
|
||||
|
||||
#ifdef CONFIG_TCC_MALLOC_HOOKS
|
||||
static void *saved_malloc_hook;
|
||||
static void *saved_free_hook;
|
||||
static void *saved_realloc_hook;
|
||||
static void *saved_memalign_hook;
|
||||
#endif
|
||||
|
||||
/* linker definitions */
|
||||
extern char _end;
|
||||
|
||||
/* TCC definitions */
|
||||
extern char __bounds_start; /* start of static bounds table */
|
||||
/* error message, just for TCC */
|
||||
const char *__bound_error_msg;
|
||||
|
||||
/* runtime error output */
|
||||
extern void rt_error(unsigned long pc, const char *fmt, ...);
|
||||
|
||||
#ifdef BOUND_STATIC
|
||||
static BoundEntry *__bound_t1[BOUND_T1_SIZE]; /* page table */
|
||||
#else
|
||||
static BoundEntry **__bound_t1; /* page table */
|
||||
#endif
|
||||
static BoundEntry *__bound_empty_t2; /* empty page, for unused pages */
|
||||
static BoundEntry *__bound_invalid_t2; /* invalid page, for invalid pointers */
|
||||
|
||||
static BoundEntry *__bound_find_region(BoundEntry *e1, void *p)
|
||||
{
|
||||
unsigned long addr, tmp;
|
||||
BoundEntry *e;
|
||||
|
||||
e = e1;
|
||||
while (e != NULL) {
|
||||
addr = (unsigned long)p;
|
||||
addr -= e->start;
|
||||
if (addr <= e->size) {
|
||||
/* put region at the head */
|
||||
tmp = e1->start;
|
||||
e1->start = e->start;
|
||||
e->start = tmp;
|
||||
tmp = e1->size;
|
||||
e1->size = e->size;
|
||||
e->size = tmp;
|
||||
return e1;
|
||||
}
|
||||
e = e->next;
|
||||
}
|
||||
/* no entry found: return empty entry or invalid entry */
|
||||
if (e1->is_invalid)
|
||||
return __bound_invalid_t2;
|
||||
else
|
||||
return __bound_empty_t2;
|
||||
}
|
||||
|
||||
/* print a bound error message */
|
||||
static void bound_error(const char *fmt, ...)
|
||||
{
|
||||
__bound_error_msg = fmt;
|
||||
*(int *)0 = 0; /* force a runtime error */
|
||||
}
|
||||
|
||||
static void bound_alloc_error(void)
|
||||
{
|
||||
bound_error("not enough memory for bound checking code");
|
||||
}
|
||||
|
||||
/* currently, tcc cannot compile that because we use GNUC extensions */
|
||||
#if !defined(__TINYC__)
|
||||
|
||||
/* return '(p + offset)' for pointer arithmetic (a pointer can reach
|
||||
the end of a region in this case */
|
||||
void * FASTCALL __bound_ptr_add(void *p, int offset)
|
||||
{
|
||||
unsigned long addr = (unsigned long)p;
|
||||
BoundEntry *e;
|
||||
#if defined(BOUND_DEBUG)
|
||||
printf("add: 0x%x %d\n", (int)p, offset);
|
||||
#endif
|
||||
|
||||
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
|
||||
e = (BoundEntry *)((char *)e +
|
||||
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
|
||||
addr -= e->start;
|
||||
if (addr > e->size) {
|
||||
e = __bound_find_region(e, p);
|
||||
addr = (unsigned long)p - e->start;
|
||||
}
|
||||
addr += offset;
|
||||
if (addr > e->size)
|
||||
return INVALID_POINTER; /* return an invalid pointer */
|
||||
return p + offset;
|
||||
}
|
||||
|
||||
/* return '(p + offset)' for pointer indirection (the resulting must
|
||||
be strictly inside the region */
|
||||
#define BOUND_PTR_INDIR(dsize) \
|
||||
void * FASTCALL __bound_ptr_indir ## dsize (void *p, int offset) \
|
||||
{ \
|
||||
unsigned long addr = (unsigned long)p; \
|
||||
BoundEntry *e; \
|
||||
\
|
||||
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; \
|
||||
e = (BoundEntry *)((char *)e + \
|
||||
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & \
|
||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS))); \
|
||||
addr -= e->start; \
|
||||
if (addr > e->size) { \
|
||||
e = __bound_find_region(e, p); \
|
||||
addr = (unsigned long)p - e->start; \
|
||||
} \
|
||||
addr += offset + dsize; \
|
||||
if (addr > e->size) \
|
||||
return INVALID_POINTER; /* return an invalid pointer */ \
|
||||
return p + offset; \
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
/* return the frame pointer of the caller */
|
||||
#define GET_CALLER_FP(fp)\
|
||||
{\
|
||||
unsigned long *fp1;\
|
||||
__asm__ __volatile__ ("movl %%ebp,%0" :"=g" (fp1));\
|
||||
fp = fp1[0];\
|
||||
}
|
||||
#else
|
||||
#error put code to extract the calling frame pointer
|
||||
#endif
|
||||
|
||||
/* called when entering a function to add all the local regions */
|
||||
void FASTCALL __bound_local_new(void *p1)
|
||||
{
|
||||
unsigned long addr, size, fp, *p = p1;
|
||||
GET_CALLER_FP(fp);
|
||||
for(;;) {
|
||||
addr = p[0];
|
||||
if (addr == 0)
|
||||
break;
|
||||
addr += fp;
|
||||
size = p[1];
|
||||
p += 2;
|
||||
__bound_new_region((void *)addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
/* called when leaving a function to delete all the local regions */
|
||||
void FASTCALL __bound_local_delete(void *p1)
|
||||
{
|
||||
unsigned long addr, fp, *p = p1;
|
||||
GET_CALLER_FP(fp);
|
||||
for(;;) {
|
||||
addr = p[0];
|
||||
if (addr == 0)
|
||||
break;
|
||||
addr += fp;
|
||||
p += 2;
|
||||
__bound_delete_region((void *)addr);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void __bound_local_new(void *p)
|
||||
{
|
||||
}
|
||||
void __bound_local_delete(void *p)
|
||||
{
|
||||
}
|
||||
|
||||
void *__bound_ptr_add(void *p, int offset)
|
||||
{
|
||||
return p + offset;
|
||||
}
|
||||
|
||||
#define BOUND_PTR_INDIR(dsize) \
|
||||
void *__bound_ptr_indir ## dsize (void *p, int offset) \
|
||||
{ \
|
||||
return p + offset; \
|
||||
}
|
||||
#endif
|
||||
|
||||
BOUND_PTR_INDIR(1)
|
||||
BOUND_PTR_INDIR(2)
|
||||
BOUND_PTR_INDIR(4)
|
||||
BOUND_PTR_INDIR(8)
|
||||
BOUND_PTR_INDIR(12)
|
||||
BOUND_PTR_INDIR(16)
|
||||
|
||||
static BoundEntry *__bound_new_page(void)
|
||||
{
|
||||
BoundEntry *page;
|
||||
int i;
|
||||
|
||||
page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE);
|
||||
if (!page)
|
||||
bound_alloc_error();
|
||||
for(i=0;i<BOUND_T2_SIZE;i++) {
|
||||
/* put empty entries */
|
||||
page[i].start = 0;
|
||||
page[i].size = EMPTY_SIZE;
|
||||
page[i].next = NULL;
|
||||
page[i].is_invalid = 0;
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
/* currently we use malloc(). Should use bound_new_page() */
|
||||
static BoundEntry *bound_new_entry(void)
|
||||
{
|
||||
BoundEntry *e;
|
||||
e = libc_malloc(sizeof(BoundEntry));
|
||||
return e;
|
||||
}
|
||||
|
||||
static void bound_free_entry(BoundEntry *e)
|
||||
{
|
||||
libc_free(e);
|
||||
}
|
||||
|
||||
static inline BoundEntry *get_page(int index)
|
||||
{
|
||||
BoundEntry *page;
|
||||
page = __bound_t1[index];
|
||||
if (page == __bound_empty_t2 || page == __bound_invalid_t2) {
|
||||
/* create a new page if necessary */
|
||||
page = __bound_new_page();
|
||||
__bound_t1[index] = page;
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
/* mark a region as being invalid (can only be used during init) */
|
||||
static void mark_invalid(unsigned long addr, unsigned long size)
|
||||
{
|
||||
unsigned long start, end;
|
||||
BoundEntry *page;
|
||||
int t1_start, t1_end, i, j, t2_start, t2_end;
|
||||
|
||||
start = addr;
|
||||
end = addr + size;
|
||||
|
||||
t2_start = (start + BOUND_T3_SIZE - 1) >> BOUND_T3_BITS;
|
||||
if (end != 0)
|
||||
t2_end = end >> BOUND_T3_BITS;
|
||||
else
|
||||
t2_end = 1 << (BOUND_T1_BITS + BOUND_T2_BITS);
|
||||
|
||||
#if 0
|
||||
printf("mark_invalid: start = %x %x\n", t2_start, t2_end);
|
||||
#endif
|
||||
|
||||
/* first we handle full pages */
|
||||
t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS;
|
||||
t1_end = t2_end >> BOUND_T2_BITS;
|
||||
|
||||
i = t2_start & (BOUND_T2_SIZE - 1);
|
||||
j = t2_end & (BOUND_T2_SIZE - 1);
|
||||
|
||||
if (t1_start == t1_end) {
|
||||
page = get_page(t2_start >> BOUND_T2_BITS);
|
||||
for(; i < j; i++) {
|
||||
page[i].size = INVALID_SIZE;
|
||||
page[i].is_invalid = 1;
|
||||
}
|
||||
} else {
|
||||
if (i > 0) {
|
||||
page = get_page(t2_start >> BOUND_T2_BITS);
|
||||
for(; i < BOUND_T2_SIZE; i++) {
|
||||
page[i].size = INVALID_SIZE;
|
||||
page[i].is_invalid = 1;
|
||||
}
|
||||
}
|
||||
for(i = t1_start; i < t1_end; i++) {
|
||||
__bound_t1[i] = __bound_invalid_t2;
|
||||
}
|
||||
if (j != 0) {
|
||||
page = get_page(t1_end);
|
||||
for(i = 0; i < j; i++) {
|
||||
page[i].size = INVALID_SIZE;
|
||||
page[i].is_invalid = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __bound_init(void)
|
||||
{
|
||||
int i;
|
||||
BoundEntry *page;
|
||||
unsigned long start, size;
|
||||
int *p;
|
||||
|
||||
/* save malloc hooks and install bound check hooks */
|
||||
install_malloc_hooks();
|
||||
|
||||
#ifndef BOUND_STATIC
|
||||
__bound_t1 = libc_malloc(BOUND_T1_SIZE * sizeof(BoundEntry *));
|
||||
if (!__bound_t1)
|
||||
bound_alloc_error();
|
||||
#endif
|
||||
__bound_empty_t2 = __bound_new_page();
|
||||
for(i=0;i<BOUND_T1_SIZE;i++) {
|
||||
__bound_t1[i] = __bound_empty_t2;
|
||||
}
|
||||
|
||||
page = __bound_new_page();
|
||||
for(i=0;i<BOUND_T2_SIZE;i++) {
|
||||
/* put invalid entries */
|
||||
page[i].start = 0;
|
||||
page[i].size = INVALID_SIZE;
|
||||
page[i].next = NULL;
|
||||
page[i].is_invalid = 1;
|
||||
}
|
||||
__bound_invalid_t2 = page;
|
||||
|
||||
/* invalid pointer zone */
|
||||
start = (unsigned long)INVALID_POINTER & ~(BOUND_T23_SIZE - 1);
|
||||
size = BOUND_T23_SIZE;
|
||||
mark_invalid(start, size);
|
||||
|
||||
#if !defined(__TINYC__) && defined(CONFIG_TCC_MALLOC_HOOKS)
|
||||
/* malloc zone is also marked invalid. can only use that with
|
||||
hooks because all libs should use the same malloc. The solution
|
||||
would be to build a new malloc for tcc. */
|
||||
start = (unsigned long)&_end;
|
||||
size = 128 * 0x100000;
|
||||
mark_invalid(start, size);
|
||||
#endif
|
||||
|
||||
/* add all static bound check values */
|
||||
p = (int *)&__bounds_start;
|
||||
while (p[0] != 0) {
|
||||
__bound_new_region((void *)p[0], p[1]);
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void add_region(BoundEntry *e,
|
||||
unsigned long start, unsigned long size)
|
||||
{
|
||||
BoundEntry *e1;
|
||||
if (e->start == 0) {
|
||||
/* no region : add it */
|
||||
e->start = start;
|
||||
e->size = size;
|
||||
} else {
|
||||
/* already regions in the list: add it at the head */
|
||||
e1 = bound_new_entry();
|
||||
e1->start = e->start;
|
||||
e1->size = e->size;
|
||||
e1->next = e->next;
|
||||
e->start = start;
|
||||
e->size = size;
|
||||
e->next = e1;
|
||||
}
|
||||
}
|
||||
|
||||
/* create a new region. It should not already exist in the region list */
|
||||
void __bound_new_region(void *p, unsigned long size)
|
||||
{
|
||||
unsigned long start, end;
|
||||
BoundEntry *page, *e, *e2;
|
||||
int t1_start, t1_end, i, t2_start, t2_end;
|
||||
|
||||
start = (unsigned long)p;
|
||||
end = start + size;
|
||||
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
|
||||
t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
|
||||
|
||||
/* start */
|
||||
page = get_page(t1_start);
|
||||
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
||||
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
||||
#ifdef BOUND_DEBUG
|
||||
printf("new %lx %lx %x %x %x %x\n",
|
||||
start, end, t1_start, t1_end, t2_start, t2_end);
|
||||
#endif
|
||||
|
||||
e = (BoundEntry *)((char *)page + t2_start);
|
||||
add_region(e, start, size);
|
||||
|
||||
if (t1_end == t1_start) {
|
||||
/* same ending page */
|
||||
e2 = (BoundEntry *)((char *)page + t2_end);
|
||||
if (e2 > e) {
|
||||
e++;
|
||||
for(;e<e2;e++) {
|
||||
e->start = start;
|
||||
e->size = size;
|
||||
}
|
||||
add_region(e, start, size);
|
||||
}
|
||||
} else {
|
||||
/* mark until end of page */
|
||||
e2 = page + BOUND_T2_SIZE;
|
||||
e++;
|
||||
for(;e<e2;e++) {
|
||||
e->start = start;
|
||||
e->size = size;
|
||||
}
|
||||
/* mark intermediate pages, if any */
|
||||
for(i=t1_start+1;i<t1_end;i++) {
|
||||
page = get_page(i);
|
||||
e2 = page + BOUND_T2_SIZE;
|
||||
for(e=page;e<e2;e++) {
|
||||
e->start = start;
|
||||
e->size = size;
|
||||
}
|
||||
}
|
||||
/* last page */
|
||||
page = get_page(t1_end);
|
||||
e2 = (BoundEntry *)((char *)page + t2_end);
|
||||
for(e=page;e<e2;e++) {
|
||||
e->start = start;
|
||||
e->size = size;
|
||||
}
|
||||
add_region(e, start, size);
|
||||
}
|
||||
}
|
||||
|
||||
/* delete a region */
|
||||
static inline void delete_region(BoundEntry *e,
|
||||
void *p, unsigned long empty_size)
|
||||
{
|
||||
unsigned long addr;
|
||||
BoundEntry *e1;
|
||||
|
||||
addr = (unsigned long)p;
|
||||
addr -= e->start;
|
||||
if (addr <= e->size) {
|
||||
/* region found is first one */
|
||||
e1 = e->next;
|
||||
if (e1 == NULL) {
|
||||
/* no more region: mark it empty */
|
||||
e->start = 0;
|
||||
e->size = empty_size;
|
||||
} else {
|
||||
/* copy next region in head */
|
||||
e->start = e1->start;
|
||||
e->size = e1->size;
|
||||
e->next = e1->next;
|
||||
bound_free_entry(e1);
|
||||
}
|
||||
} else {
|
||||
/* find the matching region */
|
||||
for(;;) {
|
||||
e1 = e;
|
||||
e = e->next;
|
||||
/* region not found: do nothing */
|
||||
if (e == NULL)
|
||||
break;
|
||||
addr = (unsigned long)p - e->start;
|
||||
if (addr <= e->size) {
|
||||
/* found: remove entry */
|
||||
e1->next = e->next;
|
||||
bound_free_entry(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* WARNING: 'p' must be the starting point of the region. */
|
||||
/* return non zero if error */
|
||||
int __bound_delete_region(void *p)
|
||||
{
|
||||
unsigned long start, end, addr, size, empty_size;
|
||||
BoundEntry *page, *e, *e2;
|
||||
int t1_start, t1_end, t2_start, t2_end, i;
|
||||
|
||||
start = (unsigned long)p;
|
||||
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
|
||||
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
||||
|
||||
/* find region size */
|
||||
page = __bound_t1[t1_start];
|
||||
e = (BoundEntry *)((char *)page + t2_start);
|
||||
addr = start - e->start;
|
||||
if (addr > e->size)
|
||||
e = __bound_find_region(e, p);
|
||||
/* test if invalid region */
|
||||
if (e->size == EMPTY_SIZE || (unsigned long)p != e->start)
|
||||
return -1;
|
||||
/* compute the size we put in invalid regions */
|
||||
if (e->is_invalid)
|
||||
empty_size = INVALID_SIZE;
|
||||
else
|
||||
empty_size = EMPTY_SIZE;
|
||||
size = e->size;
|
||||
end = start + size;
|
||||
|
||||
/* now we can free each entry */
|
||||
t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
|
||||
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
||||
|
||||
delete_region(e, p, empty_size);
|
||||
if (t1_end == t1_start) {
|
||||
/* same ending page */
|
||||
e2 = (BoundEntry *)((char *)page + t2_end);
|
||||
if (e2 > e) {
|
||||
e++;
|
||||
for(;e<e2;e++) {
|
||||
e->start = 0;
|
||||
e->size = empty_size;
|
||||
}
|
||||
delete_region(e, p, empty_size);
|
||||
}
|
||||
} else {
|
||||
/* mark until end of page */
|
||||
e2 = page + BOUND_T2_SIZE;
|
||||
e++;
|
||||
for(;e<e2;e++) {
|
||||
e->start = 0;
|
||||
e->size = empty_size;
|
||||
}
|
||||
/* mark intermediate pages, if any */
|
||||
/* XXX: should free them */
|
||||
for(i=t1_start+1;i<t1_end;i++) {
|
||||
page = get_page(i);
|
||||
e2 = page + BOUND_T2_SIZE;
|
||||
for(e=page;e<e2;e++) {
|
||||
e->start = 0;
|
||||
e->size = empty_size;
|
||||
}
|
||||
}
|
||||
/* last page */
|
||||
page = get_page(t2_end);
|
||||
e2 = (BoundEntry *)((char *)page + t2_end);
|
||||
for(e=page;e<e2;e++) {
|
||||
e->start = 0;
|
||||
e->size = empty_size;
|
||||
}
|
||||
delete_region(e, p, empty_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return the size of the region starting at p, or EMPTY_SIZE if non
|
||||
existant region. */
|
||||
static unsigned long get_region_size(void *p)
|
||||
{
|
||||
unsigned long addr = (unsigned long)p;
|
||||
BoundEntry *e;
|
||||
|
||||
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
|
||||
e = (BoundEntry *)((char *)e +
|
||||
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
|
||||
addr -= e->start;
|
||||
if (addr > e->size)
|
||||
e = __bound_find_region(e, p);
|
||||
if (e->start != (unsigned long)p)
|
||||
return EMPTY_SIZE;
|
||||
return e->size;
|
||||
}
|
||||
|
||||
/* patched memory functions */
|
||||
|
||||
static void install_malloc_hooks(void)
|
||||
{
|
||||
#ifdef CONFIG_TCC_MALLOC_HOOKS
|
||||
saved_malloc_hook = __malloc_hook;
|
||||
saved_free_hook = __free_hook;
|
||||
saved_realloc_hook = __realloc_hook;
|
||||
saved_memalign_hook = __memalign_hook;
|
||||
__malloc_hook = __bound_malloc;
|
||||
__free_hook = __bound_free;
|
||||
__realloc_hook = __bound_realloc;
|
||||
__memalign_hook = __bound_memalign;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void restore_malloc_hooks(void)
|
||||
{
|
||||
#ifdef CONFIG_TCC_MALLOC_HOOKS
|
||||
__malloc_hook = saved_malloc_hook;
|
||||
__free_hook = saved_free_hook;
|
||||
__realloc_hook = saved_realloc_hook;
|
||||
__memalign_hook = saved_memalign_hook;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *libc_malloc(size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
restore_malloc_hooks();
|
||||
ptr = malloc(size);
|
||||
install_malloc_hooks();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void libc_free(void *ptr)
|
||||
{
|
||||
restore_malloc_hooks();
|
||||
free(ptr);
|
||||
install_malloc_hooks();
|
||||
}
|
||||
|
||||
/* XXX: we should use a malloc which ensure that it is unlikely that
|
||||
two malloc'ed data have the same address if 'free' are made in
|
||||
between. */
|
||||
void *__bound_malloc(size_t size, const void *caller)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
/* we allocate one more byte to ensure the regions will be
|
||||
separated by at least one byte. With the glibc malloc, it may
|
||||
be in fact not necessary */
|
||||
ptr = libc_malloc(size + 1);
|
||||
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
__bound_new_region(ptr, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *__bound_memalign(size_t size, size_t align, const void *caller)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
restore_malloc_hooks();
|
||||
|
||||
#ifndef HAVE_MEMALIGN
|
||||
if (align > 4) {
|
||||
/* XXX: handle it ? */
|
||||
ptr = NULL;
|
||||
} else {
|
||||
/* we suppose that malloc aligns to at least four bytes */
|
||||
ptr = malloc(size + 1);
|
||||
}
|
||||
#else
|
||||
/* we allocate one more byte to ensure the regions will be
|
||||
separated by at least one byte. With the glibc malloc, it may
|
||||
be in fact not necessary */
|
||||
ptr = memalign(size + 1, align);
|
||||
#endif
|
||||
|
||||
install_malloc_hooks();
|
||||
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
__bound_new_region(ptr, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void __bound_free(void *ptr, const void *caller)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
if (__bound_delete_region(ptr) != 0)
|
||||
bound_error("freeing invalid region");
|
||||
|
||||
libc_free(ptr);
|
||||
}
|
||||
|
||||
void *__bound_realloc(void *ptr, size_t size, const void *caller)
|
||||
{
|
||||
void *ptr1;
|
||||
int old_size;
|
||||
|
||||
if (size == 0) {
|
||||
__bound_free(ptr, caller);
|
||||
return NULL;
|
||||
} else {
|
||||
ptr1 = __bound_malloc(size, caller);
|
||||
if (ptr == NULL || ptr1 == NULL)
|
||||
return ptr1;
|
||||
old_size = get_region_size(ptr);
|
||||
if (old_size == EMPTY_SIZE)
|
||||
bound_error("realloc'ing invalid pointer");
|
||||
memcpy(ptr1, ptr, old_size);
|
||||
__bound_free(ptr, caller);
|
||||
return ptr1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_TCC_MALLOC_HOOKS
|
||||
void *__bound_calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
size = size * nmemb;
|
||||
ptr = __bound_malloc(size, NULL);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void bound_dump(void)
|
||||
{
|
||||
BoundEntry *page, *e;
|
||||
int i, j;
|
||||
|
||||
printf("region dump:\n");
|
||||
for(i=0;i<BOUND_T1_SIZE;i++) {
|
||||
page = __bound_t1[i];
|
||||
for(j=0;j<BOUND_T2_SIZE;j++) {
|
||||
e = page + j;
|
||||
/* do not print invalid or empty entries */
|
||||
if (e->size != EMPTY_SIZE && e->start != 0) {
|
||||
printf("%08x:",
|
||||
(i << (BOUND_T2_BITS + BOUND_T3_BITS)) +
|
||||
(j << BOUND_T3_BITS));
|
||||
do {
|
||||
printf(" %08lx:%08lx", e->start, e->start + e->size);
|
||||
e = e->next;
|
||||
} while (e != NULL);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* some useful checked functions */
|
||||
|
||||
/* check that (p ... p + size - 1) lies inside 'p' region, if any */
|
||||
static void __bound_check(const void *p, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return;
|
||||
p = __bound_ptr_add((void *)p, size);
|
||||
if (p == INVALID_POINTER)
|
||||
bound_error("invalid pointer");
|
||||
}
|
||||
|
||||
void *__bound_memcpy(void *dst, const void *src, size_t size)
|
||||
{
|
||||
__bound_check(dst, size);
|
||||
__bound_check(src, size);
|
||||
/* check also region overlap */
|
||||
if (src >= dst && src < dst + size)
|
||||
bound_error("overlapping regions in memcpy()");
|
||||
return memcpy(dst, src, size);
|
||||
}
|
||||
|
||||
void *__bound_memmove(void *dst, const void *src, size_t size)
|
||||
{
|
||||
__bound_check(dst, size);
|
||||
__bound_check(src, size);
|
||||
return memmove(dst, src, size);
|
||||
}
|
||||
|
||||
void *__bound_memset(void *dst, int c, size_t size)
|
||||
{
|
||||
__bound_check(dst, size);
|
||||
return memset(dst, c, size);
|
||||
}
|
||||
|
||||
/* XXX: could be optimized */
|
||||
int __bound_strlen(const char *s)
|
||||
{
|
||||
const char *p;
|
||||
int len;
|
||||
|
||||
len = 0;
|
||||
for(;;) {
|
||||
p = __bound_ptr_indir1((char *)s, len);
|
||||
if (p == INVALID_POINTER)
|
||||
bound_error("bad pointer in strlen()");
|
||||
if (*p == '\0')
|
||||
break;
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
char *__bound_strcpy(char *dst, const char *src)
|
||||
{
|
||||
int len;
|
||||
len = __bound_strlen(src);
|
||||
return __bound_memcpy(dst, src, len + 1);
|
||||
}
|
||||
|
214
programs/develop/metcc/trunk/source/boundtest.c
Normal file
214
programs/develop/metcc/trunk/source/boundtest.c
Normal file
@ -0,0 +1,214 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define NB_ITS 1000000
|
||||
//#define NB_ITS 1
|
||||
#define TAB_SIZE 100
|
||||
|
||||
int tab[TAB_SIZE];
|
||||
int ret_sum;
|
||||
char tab3[256];
|
||||
|
||||
int test1(void)
|
||||
{
|
||||
int i, sum = 0;
|
||||
for(i=0;i<TAB_SIZE;i++) {
|
||||
sum += tab[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* error */
|
||||
int test2(void)
|
||||
{
|
||||
int i, sum = 0;
|
||||
for(i=0;i<TAB_SIZE + 1;i++) {
|
||||
sum += tab[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* actually, profiling test */
|
||||
int test3(void)
|
||||
{
|
||||
int sum;
|
||||
int i, it;
|
||||
|
||||
sum = 0;
|
||||
for(it=0;it<NB_ITS;it++) {
|
||||
for(i=0;i<TAB_SIZE;i++) {
|
||||
sum += tab[i];
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* ok */
|
||||
int test4(void)
|
||||
{
|
||||
int i, sum = 0;
|
||||
int *tab4;
|
||||
|
||||
tab4 = malloc(20 * sizeof(int));
|
||||
for(i=0;i<20;i++) {
|
||||
sum += tab4[i];
|
||||
}
|
||||
free(tab4);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* error */
|
||||
int test5(void)
|
||||
{
|
||||
int i, sum = 0;
|
||||
int *tab4;
|
||||
|
||||
tab4 = malloc(20 * sizeof(int));
|
||||
for(i=0;i<21;i++) {
|
||||
sum += tab4[i];
|
||||
}
|
||||
free(tab4);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* error */
|
||||
/* XXX: currently: bug */
|
||||
int test6(void)
|
||||
{
|
||||
int i, sum = 0;
|
||||
int *tab4;
|
||||
|
||||
tab4 = malloc(20 * sizeof(int));
|
||||
free(tab4);
|
||||
for(i=0;i<21;i++) {
|
||||
sum += tab4[i];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* error */
|
||||
int test7(void)
|
||||
{
|
||||
int i, sum = 0;
|
||||
int *p;
|
||||
|
||||
for(i=0;i<TAB_SIZE + 1;i++) {
|
||||
p = &tab[i];
|
||||
if (i == TAB_SIZE)
|
||||
printf("i=%d %x\n", i, p);
|
||||
sum += *p;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* ok */
|
||||
int test8(void)
|
||||
{
|
||||
int i, sum = 0;
|
||||
int tab[10];
|
||||
|
||||
for(i=0;i<10;i++) {
|
||||
sum += tab[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* error */
|
||||
int test9(void)
|
||||
{
|
||||
int i, sum = 0;
|
||||
char tab[10];
|
||||
|
||||
for(i=0;i<11;i++) {
|
||||
sum += tab[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* ok */
|
||||
int test10(void)
|
||||
{
|
||||
char tab[10];
|
||||
char tab1[10];
|
||||
|
||||
memset(tab, 0, 10);
|
||||
memcpy(tab, tab1, 10);
|
||||
memmove(tab, tab1, 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* error */
|
||||
int test11(void)
|
||||
{
|
||||
char tab[10];
|
||||
|
||||
memset(tab, 0, 11);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* error */
|
||||
int test12(void)
|
||||
{
|
||||
void *ptr;
|
||||
ptr = malloc(10);
|
||||
free(ptr);
|
||||
free(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* error */
|
||||
int test13(void)
|
||||
{
|
||||
char pad1 = 0;
|
||||
char tab[10];
|
||||
char pad2 = 0;
|
||||
memset(tab, 'a', sizeof(tab));
|
||||
return strlen(tab);
|
||||
}
|
||||
|
||||
int (*table_test[])(void) = {
|
||||
test1,
|
||||
test1,
|
||||
test2,
|
||||
test3,
|
||||
test4,
|
||||
test5,
|
||||
test6,
|
||||
test7,
|
||||
test8,
|
||||
test9,
|
||||
test10,
|
||||
test11,
|
||||
test12,
|
||||
test13,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int index;
|
||||
int (*ftest)(void);
|
||||
|
||||
if (argc < 2) {
|
||||
printf("usage: boundtest n\n"
|
||||
"test TCC bound checking system\n"
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
index = 0;
|
||||
if (argc >= 2)
|
||||
index = atoi(argv[1]);
|
||||
/* well, we also use bounds on this ! */
|
||||
ftest = table_test[index];
|
||||
ftest();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* without bound 0.77 s
|
||||
* with bounds 4.73
|
||||
*/
|
2548
programs/develop/metcc/trunk/source/c67-gen.c
Normal file
2548
programs/develop/metcc/trunk/source/c67-gen.c
Normal file
File diff suppressed because it is too large
Load Diff
446
programs/develop/metcc/trunk/source/coff.h
Normal file
446
programs/develop/metcc/trunk/source/coff.h
Normal file
@ -0,0 +1,446 @@
|
||||
/**************************************************************************/
|
||||
/* COFF.H */
|
||||
/* COFF data structures and related definitions used by the linker */
|
||||
/**************************************************************************/
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* COFF FILE HEADER */
|
||||
/*------------------------------------------------------------------------*/
|
||||
struct filehdr {
|
||||
unsigned short f_magic; /* magic number */
|
||||
unsigned short f_nscns; /* number of sections */
|
||||
long f_timdat; /* time & date stamp */
|
||||
long f_symptr; /* file pointer to symtab */
|
||||
long f_nsyms; /* number of symtab entries */
|
||||
unsigned short f_opthdr; /* sizeof(optional hdr) */
|
||||
unsigned short f_flags; /* flags */
|
||||
unsigned short f_TargetID; /* for C6x = 0x0099 */
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* File header flags */
|
||||
/*------------------------------------------------------------------------*/
|
||||
#define F_RELFLG 0x01 /* relocation info stripped from file */
|
||||
#define F_EXEC 0x02 /* file is executable (no unresolved refs) */
|
||||
#define F_LNNO 0x04 /* line nunbers stripped from file */
|
||||
#define F_LSYMS 0x08 /* local symbols stripped from file */
|
||||
#define F_GSP10 0x10 /* 34010 version */
|
||||
#define F_GSP20 0x20 /* 34020 version */
|
||||
#define F_SWABD 0x40 /* bytes swabbed (in names) */
|
||||
#define F_AR16WR 0x80 /* byte ordering of an AR16WR (PDP-11) */
|
||||
#define F_LITTLE 0x100 /* byte ordering of an AR32WR (vax) */
|
||||
#define F_BIG 0x200 /* byte ordering of an AR32W (3B, maxi) */
|
||||
#define F_PATCH 0x400 /* contains "patch" list in optional header */
|
||||
#define F_NODF 0x400
|
||||
|
||||
#define F_VERSION (F_GSP10 | F_GSP20)
|
||||
#define F_BYTE_ORDER (F_LITTLE | F_BIG)
|
||||
#define FILHDR struct filehdr
|
||||
|
||||
//#define FILHSZ sizeof(FILHDR)
|
||||
#define FILHSZ 22 // above rounds to align on 4 bytes which causes problems
|
||||
|
||||
#define COFF_C67_MAGIC 0x00c2
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Macros to recognize magic numbers */
|
||||
/*------------------------------------------------------------------------*/
|
||||
#define ISMAGIC(x) (((unsigned short)(x))==(unsigned short)magic)
|
||||
#define ISARCHIVE(x) ((((unsigned short)(x))==(unsigned short)ARTYPE))
|
||||
#define BADMAGIC(x) (((unsigned short)(x) & 0x8080) && !ISMAGIC(x))
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OPTIONAL FILE HEADER */
|
||||
/*------------------------------------------------------------------------*/
|
||||
typedef struct aouthdr {
|
||||
short magic; /* see magic.h */
|
||||
short vstamp; /* version stamp */
|
||||
long tsize; /* text size in bytes, padded to FW bdry*/
|
||||
long dsize; /* initialized data " " */
|
||||
long bsize; /* uninitialized data " " */
|
||||
long entrypt; /* entry pt. */
|
||||
long text_start; /* base of text used for this file */
|
||||
long data_start; /* base of data used for this file */
|
||||
} AOUTHDR;
|
||||
|
||||
#define AOUTSZ sizeof(AOUTHDR)
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* When a UNIX aout header is to be built in the optional header, */
|
||||
/* the following magic numbers can appear in that header: */
|
||||
/* */
|
||||
/* AOUT1MAGIC : default : readonly sharable text segment */
|
||||
/* AOUT2MAGIC: : writable text segment */
|
||||
/* PAGEMAGIC : : configured for paging */
|
||||
/*----------------------------------------------------------------------*/
|
||||
#define AOUT1MAGIC 0410
|
||||
#define AOUT2MAGIC 0407
|
||||
#define PAGEMAGIC 0413
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* COMMON ARCHIVE FILE STRUCTURES */
|
||||
/* */
|
||||
/* ARCHIVE File Organization: */
|
||||
/* _______________________________________________ */
|
||||
/* |__________ARCHIVE_MAGIC_STRING_______________| */
|
||||
/* |__________ARCHIVE_FILE_MEMBER_1______________| */
|
||||
/* | | */
|
||||
/* | Archive File Header "ar_hdr" | */
|
||||
/* |.............................................| */
|
||||
/* | Member Contents | */
|
||||
/* | 1. External symbol directory | */
|
||||
/* | 2. Text file | */
|
||||
/* |_____________________________________________| */
|
||||
/* |________ARCHIVE_FILE_MEMBER_2________________| */
|
||||
/* | "ar_hdr" | */
|
||||
/* |.............................................| */
|
||||
/* | Member Contents (.o or text file) | */
|
||||
/* |_____________________________________________| */
|
||||
/* | . . . | */
|
||||
/* | . . . | */
|
||||
/* | . . . | */
|
||||
/* |_____________________________________________| */
|
||||
/* |________ARCHIVE_FILE_MEMBER_n________________| */
|
||||
/* | "ar_hdr" | */
|
||||
/* |.............................................| */
|
||||
/* | Member Contents | */
|
||||
/* |_____________________________________________| */
|
||||
/* */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#define COFF_ARMAG "!<arch>\n"
|
||||
#define SARMAG 8
|
||||
#define ARFMAG "`\n"
|
||||
|
||||
struct ar_hdr /* archive file member header - printable ascii */
|
||||
{
|
||||
char ar_name[16]; /* file member name - `/' terminated */
|
||||
char ar_date[12]; /* file member date - decimal */
|
||||
char ar_uid[6]; /* file member user id - decimal */
|
||||
char ar_gid[6]; /* file member group id - decimal */
|
||||
char ar_mode[8]; /* file member mode - octal */
|
||||
char ar_size[10]; /* file member size - decimal */
|
||||
char ar_fmag[2]; /* ARFMAG - string to end header */
|
||||
};
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* SECTION HEADER */
|
||||
/*------------------------------------------------------------------------*/
|
||||
struct scnhdr {
|
||||
char s_name[8]; /* section name */
|
||||
long s_paddr; /* physical address */
|
||||
long s_vaddr; /* virtual address */
|
||||
long s_size; /* section size */
|
||||
long s_scnptr; /* file ptr to raw data for section */
|
||||
long s_relptr; /* file ptr to relocation */
|
||||
long s_lnnoptr; /* file ptr to line numbers */
|
||||
unsigned int s_nreloc; /* number of relocation entries */
|
||||
unsigned int s_nlnno; /* number of line number entries */
|
||||
unsigned int s_flags; /* flags */
|
||||
unsigned short s_reserved; /* reserved byte */
|
||||
unsigned short s_page; /* memory page id */
|
||||
};
|
||||
|
||||
#define SCNHDR struct scnhdr
|
||||
#define SCNHSZ sizeof(SCNHDR)
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Define constants for names of "special" sections */
|
||||
/*------------------------------------------------------------------------*/
|
||||
//#define _TEXT ".text"
|
||||
#define _DATA ".data"
|
||||
#define _BSS ".bss"
|
||||
#define _CINIT ".cinit"
|
||||
#define _TV ".tv"
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* The low 4 bits of s_flags is used as a section "type" */
|
||||
/*------------------------------------------------------------------------*/
|
||||
#define STYP_REG 0x00 /* "regular" : allocated, relocated, loaded */
|
||||
#define STYP_DSECT 0x01 /* "dummy" : not allocated, relocated, not loaded */
|
||||
#define STYP_NOLOAD 0x02 /* "noload" : allocated, relocated, not loaded */
|
||||
#define STYP_GROUP 0x04 /* "grouped" : formed of input sections */
|
||||
#define STYP_PAD 0x08 /* "padding" : not allocated, not relocated, loaded */
|
||||
#define STYP_COPY 0x10 /* "copy" : used for C init tables -
|
||||
not allocated, relocated,
|
||||
loaded; reloc & lineno
|
||||
entries processed normally */
|
||||
#define STYP_TEXT 0x20 /* section contains text only */
|
||||
#define STYP_DATA 0x40 /* section contains data only */
|
||||
#define STYP_BSS 0x80 /* section contains bss only */
|
||||
|
||||
#define STYP_ALIGN 0x100 /* align flag passed by old version assemblers */
|
||||
#define ALIGN_MASK 0x0F00 /* part of s_flags that is used for align vals */
|
||||
#define ALIGNSIZE(x) (1 << ((x & ALIGN_MASK) >> 8))
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* RELOCATION ENTRIES */
|
||||
/*------------------------------------------------------------------------*/
|
||||
struct reloc
|
||||
{
|
||||
long r_vaddr; /* (virtual) address of reference */
|
||||
short r_symndx; /* index into symbol table */
|
||||
unsigned short r_disp; /* additional bits for address calculation */
|
||||
unsigned short r_type; /* relocation type */
|
||||
};
|
||||
|
||||
#define RELOC struct reloc
|
||||
#define RELSZ 10 /* sizeof(RELOC) */
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* define all relocation types */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
#define R_ABS 0 /* absolute address - no relocation */
|
||||
#define R_DIR16 01 /* UNUSED */
|
||||
#define R_REL16 02 /* UNUSED */
|
||||
#define R_DIR24 04 /* UNUSED */
|
||||
#define R_REL24 05 /* 24 bits, direct */
|
||||
#define R_DIR32 06 /* UNUSED */
|
||||
#define R_RELBYTE 017 /* 8 bits, direct */
|
||||
#define R_RELWORD 020 /* 16 bits, direct */
|
||||
#define R_RELLONG 021 /* 32 bits, direct */
|
||||
#define R_PCRBYTE 022 /* 8 bits, PC-relative */
|
||||
#define R_PCRWORD 023 /* 16 bits, PC-relative */
|
||||
#define R_PCRLONG 024 /* 32 bits, PC-relative */
|
||||
#define R_OCRLONG 030 /* GSP: 32 bits, one's complement direct */
|
||||
#define R_GSPPCR16 031 /* GSP: 16 bits, PC relative (in words) */
|
||||
#define R_GSPOPR32 032 /* GSP: 32 bits, direct big-endian */
|
||||
#define R_PARTLS16 040 /* Brahma: 16 bit offset of 24 bit address*/
|
||||
#define R_PARTMS8 041 /* Brahma: 8 bit page of 24 bit address */
|
||||
#define R_PARTLS7 050 /* DSP: 7 bit offset of 16 bit address */
|
||||
#define R_PARTMS9 051 /* DSP: 9 bit page of 16 bit address */
|
||||
#define R_REL13 052 /* DSP: 13 bits, direct */
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* LINE NUMBER ENTRIES */
|
||||
/*------------------------------------------------------------------------*/
|
||||
struct lineno
|
||||
{
|
||||
union
|
||||
{
|
||||
long l_symndx ; /* sym. table index of function name
|
||||
iff l_lnno == 0 */
|
||||
long l_paddr ; /* (physical) address of line number */
|
||||
} l_addr ;
|
||||
unsigned short l_lnno ; /* line number */
|
||||
};
|
||||
|
||||
#define LINENO struct lineno
|
||||
#define LINESZ 6 /* sizeof(LINENO) */
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* STORAGE CLASSES */
|
||||
/*------------------------------------------------------------------------*/
|
||||
#define C_EFCN -1 /* physical end of function */
|
||||
#define C_NULL 0
|
||||
#define C_AUTO 1 /* automatic variable */
|
||||
#define C_EXT 2 /* external symbol */
|
||||
#define C_STAT 3 /* static */
|
||||
#define C_REG 4 /* register variable */
|
||||
#define C_EXTDEF 5 /* external definition */
|
||||
#define C_LABEL 6 /* label */
|
||||
#define C_ULABEL 7 /* undefined label */
|
||||
#define C_MOS 8 /* member of structure */
|
||||
#define C_ARG 9 /* function argument */
|
||||
#define C_STRTAG 10 /* structure tag */
|
||||
#define C_MOU 11 /* member of union */
|
||||
#define C_UNTAG 12 /* union tag */
|
||||
#define C_TPDEF 13 /* type definition */
|
||||
#define C_USTATIC 14 /* undefined static */
|
||||
#define C_ENTAG 15 /* enumeration tag */
|
||||
#define C_MOE 16 /* member of enumeration */
|
||||
#define C_REGPARM 17 /* register parameter */
|
||||
#define C_FIELD 18 /* bit field */
|
||||
|
||||
#define C_BLOCK 100 /* ".bb" or ".eb" */
|
||||
#define C_FCN 101 /* ".bf" or ".ef" */
|
||||
#define C_EOS 102 /* end of structure */
|
||||
#define C_FILE 103 /* file name */
|
||||
#define C_LINE 104 /* dummy sclass for line number entry */
|
||||
#define C_ALIAS 105 /* duplicate tag */
|
||||
#define C_HIDDEN 106 /* special storage class for external */
|
||||
/* symbols in dmert public libraries */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* SYMBOL TABLE ENTRIES */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#define SYMNMLEN 8 /* Number of characters in a symbol name */
|
||||
#define FILNMLEN 14 /* Number of characters in a file name */
|
||||
#define DIMNUM 4 /* Number of array dimensions in auxiliary entry */
|
||||
|
||||
|
||||
struct syment
|
||||
{
|
||||
union
|
||||
{
|
||||
char _n_name[SYMNMLEN]; /* old COFF version */
|
||||
struct
|
||||
{
|
||||
long _n_zeroes; /* new == 0 */
|
||||
long _n_offset; /* offset into string table */
|
||||
} _n_n;
|
||||
char *_n_nptr[2]; /* allows for overlaying */
|
||||
} _n;
|
||||
long n_value; /* value of symbol */
|
||||
short n_scnum; /* section number */
|
||||
unsigned short n_type; /* type and derived type */
|
||||
char n_sclass; /* storage class */
|
||||
char n_numaux; /* number of aux. entries */
|
||||
};
|
||||
|
||||
#define n_name _n._n_name
|
||||
#define n_nptr _n._n_nptr[1]
|
||||
#define n_zeroes _n._n_n._n_zeroes
|
||||
#define n_offset _n._n_n._n_offset
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Relocatable symbols have a section number of the */
|
||||
/* section in which they are defined. Otherwise, section */
|
||||
/* numbers have the following meanings: */
|
||||
/*------------------------------------------------------------------------*/
|
||||
#define N_UNDEF 0 /* undefined symbol */
|
||||
#define N_ABS -1 /* value of symbol is absolute */
|
||||
#define N_DEBUG -2 /* special debugging symbol */
|
||||
#define N_TV (unsigned short)-3 /* needs transfer vector (preload) */
|
||||
#define P_TV (unsigned short)-4 /* needs transfer vector (postload) */
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* The fundamental type of a symbol packed into the low */
|
||||
/* 4 bits of the word. */
|
||||
/*------------------------------------------------------------------------*/
|
||||
#define _EF ".ef"
|
||||
|
||||
#define T_NULL 0 /* no type info */
|
||||
#define T_ARG 1 /* function argument (only used by compiler) */
|
||||
#define T_CHAR 2 /* character */
|
||||
#define T_SHORT 3 /* short integer */
|
||||
#define T_INT 4 /* integer */
|
||||
#define T_LONG 5 /* long integer */
|
||||
#define T_FLOAT 6 /* floating point */
|
||||
#define T_DOUBLE 7 /* double word */
|
||||
#define T_STRUCT 8 /* structure */
|
||||
#define T_UNION 9 /* union */
|
||||
#define T_ENUM 10 /* enumeration */
|
||||
#define T_MOE 11 /* member of enumeration */
|
||||
#define T_UCHAR 12 /* unsigned character */
|
||||
#define T_USHORT 13 /* unsigned short */
|
||||
#define T_UINT 14 /* unsigned integer */
|
||||
#define T_ULONG 15 /* unsigned long */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* derived types are: */
|
||||
/*------------------------------------------------------------------------*/
|
||||
#define DT_NON 0 /* no derived type */
|
||||
#define DT_PTR 1 /* pointer */
|
||||
#define DT_FCN 2 /* function */
|
||||
#define DT_ARY 3 /* array */
|
||||
|
||||
#define MKTYPE(basic, d1,d2,d3,d4,d5,d6) \
|
||||
((basic) | ((d1) << 4) | ((d2) << 6) | ((d3) << 8) |\
|
||||
((d4) << 10) | ((d5) << 12) | ((d6) << 14))
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* type packing constants and macros */
|
||||
/*------------------------------------------------------------------------*/
|
||||
#define N_BTMASK_COFF 017
|
||||
#define N_TMASK_COFF 060
|
||||
#define N_TMASK1_COFF 0300
|
||||
#define N_TMASK2_COFF 0360
|
||||
#define N_BTSHFT_COFF 4
|
||||
#define N_TSHIFT_COFF 2
|
||||
|
||||
#define BTYPE_COFF(x) ((x) & N_BTMASK_COFF)
|
||||
#define ISINT(x) (((x) >= T_CHAR && (x) <= T_LONG) || \
|
||||
((x) >= T_UCHAR && (x) <= T_ULONG) || (x) == T_ENUM)
|
||||
#define ISFLT_COFF(x) ((x) == T_DOUBLE || (x) == T_FLOAT)
|
||||
#define ISPTR_COFF(x) (((x) & N_TMASK_COFF) == (DT_PTR << N_BTSHFT_COFF))
|
||||
#define ISFCN_COFF(x) (((x) & N_TMASK_COFF) == (DT_FCN << N_BTSHFT_COFF))
|
||||
#define ISARY_COFF(x) (((x) & N_TMASK_COFF) == (DT_ARY << N_BTSHFT_COFF))
|
||||
#define ISTAG_COFF(x) ((x)==C_STRTAG || (x)==C_UNTAG || (x)==C_ENTAG)
|
||||
|
||||
#define INCREF_COFF(x) ((((x)&~N_BTMASK_COFF)<<N_TSHIFT_COFF)|(DT_PTR<<N_BTSHFT_COFF)|(x&N_BTMASK_COFF))
|
||||
#define DECREF_COFF(x) ((((x)>>N_TSHIFT_COFF)&~N_BTMASK_COFF)|((x)&N_BTMASK_COFF))
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* AUXILIARY SYMBOL ENTRY */
|
||||
/*------------------------------------------------------------------------*/
|
||||
union auxent
|
||||
{
|
||||
struct
|
||||
{
|
||||
long x_tagndx; /* str, un, or enum tag indx */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned short x_lnno; /* declaration line number */
|
||||
unsigned short x_size; /* str, union, array size */
|
||||
} x_lnsz;
|
||||
long x_fsize; /* size of function */
|
||||
} x_misc;
|
||||
union
|
||||
{
|
||||
struct /* if ISFCN, tag, or .bb */
|
||||
{
|
||||
long x_lnnoptr; /* ptr to fcn line # */
|
||||
long x_endndx; /* entry ndx past block end */
|
||||
} x_fcn;
|
||||
struct /* if ISARY, up to 4 dimen. */
|
||||
{
|
||||
unsigned short x_dimen[DIMNUM];
|
||||
} x_ary;
|
||||
} x_fcnary;
|
||||
unsigned short x_regcount; /* number of registers used by func */
|
||||
} x_sym;
|
||||
struct
|
||||
{
|
||||
char x_fname[FILNMLEN];
|
||||
} x_file;
|
||||
struct
|
||||
{
|
||||
long x_scnlen; /* section length */
|
||||
unsigned short x_nreloc; /* number of relocation entries */
|
||||
unsigned short x_nlinno; /* number of line numbers */
|
||||
} x_scn;
|
||||
};
|
||||
|
||||
#define SYMENT struct syment
|
||||
#define SYMESZ 18 /* sizeof(SYMENT) */
|
||||
|
||||
#define AUXENT union auxent
|
||||
#define AUXESZ 18 /* sizeof(AUXENT) */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* NAMES OF "SPECIAL" SYMBOLS */
|
||||
/*------------------------------------------------------------------------*/
|
||||
#define _STEXT ".text"
|
||||
#define _ETEXT "etext"
|
||||
#define _SDATA ".data"
|
||||
#define _EDATA "edata"
|
||||
#define _SBSS ".bss"
|
||||
#define _END "end"
|
||||
#define _CINITPTR "cinit"
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* ENTRY POINT SYMBOLS */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define _START "_start"
|
||||
#define _MAIN "_main"
|
||||
/* _CSTART "_c_int00" (defined in params.h) */
|
||||
|
||||
|
||||
#define _TVORIG "_tvorig"
|
||||
#define _TORIGIN "_torigin"
|
||||
#define _DORIGIN "_dorigin"
|
||||
|
||||
#define _SORIGIN "_sorigin"
|
7
programs/develop/metcc/trunk/source/config.h
Normal file
7
programs/develop/metcc/trunk/source/config.h
Normal file
@ -0,0 +1,7 @@
|
||||
/* Automatically generated by configure - do not modify */
|
||||
#define CONFIG_TCCDIR "/usr/local/lib/tcc"
|
||||
#define GCC_MAJOR 3
|
||||
#define HOST_I386 1
|
||||
#define TCC_VERSION "0.9.23"
|
||||
//#define TCC_TARGET_PE
|
||||
#define TCC_TARGET_MEOS
|
1627
programs/develop/metcc/trunk/source/elf.h
Normal file
1627
programs/develop/metcc/trunk/source/elf.h
Normal file
File diff suppressed because it is too large
Load Diff
57
programs/develop/metcc/trunk/source/float.h
Normal file
57
programs/develop/metcc/trunk/source/float.h
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef _FLOAT_H_
|
||||
#define _FLOAT_H_
|
||||
|
||||
#define FLT_RADIX 2
|
||||
|
||||
/* IEEE float */
|
||||
#define FLT_MANT_DIG 24
|
||||
#define FLT_DIG 6
|
||||
#define FLT_ROUNDS 1
|
||||
#define FLT_EPSILON 1.19209290e-07F
|
||||
#define FLT_MIN_EXP (-125)
|
||||
#define FLT_MIN 1.17549435e-38F
|
||||
#define FLT_MIN_10_EXP (-37)
|
||||
#define FLT_MAX_EXP 128
|
||||
#define FLT_MAX 3.40282347e+38F
|
||||
#define FLT_MAX_10_EXP 38
|
||||
|
||||
/* IEEE double */
|
||||
#define DBL_MANT_DIG 53
|
||||
#define DBL_DIG 15
|
||||
#define DBL_EPSILON 2.2204460492503131e-16
|
||||
#define DBL_MIN_EXP (-1021)
|
||||
#define DBL_MIN 2.2250738585072014e-308
|
||||
#define DBL_MIN_10_EXP (-307)
|
||||
#define DBL_MAX_EXP 1024
|
||||
#define DBL_MAX 1.7976931348623157e+308
|
||||
#define DBL_MAX_10_EXP 308
|
||||
|
||||
/* horrible intel long double */
|
||||
#ifdef __i386__
|
||||
|
||||
#define LDBL_MANT_DIG 64
|
||||
#define LDBL_DIG 18
|
||||
#define LDBL_EPSILON 1.08420217248550443401e-19L
|
||||
#define LDBL_MIN_EXP (-16381)
|
||||
#define LDBL_MIN 3.36210314311209350626e-4932L
|
||||
#define LDBL_MIN_10_EXP (-4931)
|
||||
#define LDBL_MAX_EXP 16384
|
||||
#define LDBL_MAX 1.18973149535723176502e+4932L
|
||||
#define LDBL_MAX_10_EXP 4932
|
||||
|
||||
#else
|
||||
|
||||
/* same as IEEE double */
|
||||
#define LDBL_MANT_DIG 53
|
||||
#define LDBL_DIG 15
|
||||
#define LDBL_EPSILON 2.2204460492503131e-16
|
||||
#define LDBL_MIN_EXP (-1021)
|
||||
#define LDBL_MIN 2.2250738585072014e-308
|
||||
#define LDBL_MIN_10_EXP (-307)
|
||||
#define LDBL_MAX_EXP 1024
|
||||
#define LDBL_MAX 1.7976931348623157e+308
|
||||
#define LDBL_MAX_10_EXP 308
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _FLOAT_H_ */
|
1183
programs/develop/metcc/trunk/source/i386-asm.c
Normal file
1183
programs/develop/metcc/trunk/source/i386-asm.c
Normal file
File diff suppressed because it is too large
Load Diff
446
programs/develop/metcc/trunk/source/i386-asm.h
Normal file
446
programs/develop/metcc/trunk/source/i386-asm.h
Normal file
@ -0,0 +1,446 @@
|
||||
DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
|
||||
DEF_ASM_OP0(popa, 0x61)
|
||||
DEF_ASM_OP0(clc, 0xf8)
|
||||
DEF_ASM_OP0(cld, 0xfc)
|
||||
DEF_ASM_OP0(cli, 0xfa)
|
||||
DEF_ASM_OP0(clts, 0x0f06)
|
||||
DEF_ASM_OP0(cmc, 0xf5)
|
||||
DEF_ASM_OP0(lahf, 0x9f)
|
||||
DEF_ASM_OP0(sahf, 0x9e)
|
||||
DEF_ASM_OP0(pushfl, 0x9c)
|
||||
DEF_ASM_OP0(popfl, 0x9d)
|
||||
DEF_ASM_OP0(pushf, 0x9c)
|
||||
DEF_ASM_OP0(popf, 0x9d)
|
||||
DEF_ASM_OP0(stc, 0xf9)
|
||||
DEF_ASM_OP0(std, 0xfd)
|
||||
DEF_ASM_OP0(sti, 0xfb)
|
||||
DEF_ASM_OP0(aaa, 0x37)
|
||||
DEF_ASM_OP0(aas, 0x3f)
|
||||
DEF_ASM_OP0(daa, 0x27)
|
||||
DEF_ASM_OP0(das, 0x2f)
|
||||
DEF_ASM_OP0(aad, 0xd50a)
|
||||
DEF_ASM_OP0(aam, 0xd40a)
|
||||
DEF_ASM_OP0(cbw, 0x6698)
|
||||
DEF_ASM_OP0(cwd, 0x6699)
|
||||
DEF_ASM_OP0(cwde, 0x98)
|
||||
DEF_ASM_OP0(cdq, 0x99)
|
||||
DEF_ASM_OP0(cbtw, 0x6698)
|
||||
DEF_ASM_OP0(cwtl, 0x98)
|
||||
DEF_ASM_OP0(cwtd, 0x6699)
|
||||
DEF_ASM_OP0(cltd, 0x99)
|
||||
DEF_ASM_OP0(int3, 0xcc)
|
||||
DEF_ASM_OP0(into, 0xce)
|
||||
DEF_ASM_OP0(iret, 0xcf)
|
||||
DEF_ASM_OP0(rsm, 0x0faa)
|
||||
DEF_ASM_OP0(hlt, 0xf4)
|
||||
DEF_ASM_OP0(wait, 0x9b)
|
||||
DEF_ASM_OP0(nop, 0x90)
|
||||
DEF_ASM_OP0(xlat, 0xd7)
|
||||
|
||||
/* strings */
|
||||
ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
|
||||
ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
|
||||
|
||||
ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
|
||||
ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
|
||||
|
||||
ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
|
||||
ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
|
||||
|
||||
ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
|
||||
ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
|
||||
|
||||
ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
|
||||
ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
|
||||
|
||||
ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
|
||||
ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
|
||||
|
||||
/* bits */
|
||||
|
||||
ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
|
||||
ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
|
||||
|
||||
ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
|
||||
ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
|
||||
|
||||
ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
|
||||
ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
|
||||
|
||||
ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
|
||||
ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
|
||||
|
||||
ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
|
||||
ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
|
||||
|
||||
/* prefixes */
|
||||
DEF_ASM_OP0(aword, 0x67)
|
||||
DEF_ASM_OP0(addr16, 0x67)
|
||||
DEF_ASM_OP0(word, 0x66)
|
||||
DEF_ASM_OP0(data16, 0x66)
|
||||
DEF_ASM_OP0(lock, 0xf0)
|
||||
DEF_ASM_OP0(rep, 0xf3)
|
||||
DEF_ASM_OP0(repe, 0xf3)
|
||||
DEF_ASM_OP0(repz, 0xf3)
|
||||
DEF_ASM_OP0(repne, 0xf2)
|
||||
DEF_ASM_OP0(repnz, 0xf2)
|
||||
|
||||
DEF_ASM_OP0(invd, 0x0f08)
|
||||
DEF_ASM_OP0(wbinvd, 0x0f09)
|
||||
DEF_ASM_OP0(cpuid, 0x0fa2)
|
||||
DEF_ASM_OP0(wrmsr, 0x0f30)
|
||||
DEF_ASM_OP0(rdtsc, 0x0f31)
|
||||
DEF_ASM_OP0(rdmsr, 0x0f32)
|
||||
DEF_ASM_OP0(rdpmc, 0x0f33)
|
||||
DEF_ASM_OP0(ud2, 0x0f0b)
|
||||
|
||||
/* NOTE: we took the same order as gas opcode definition order */
|
||||
ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
|
||||
ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
|
||||
ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
|
||||
ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
|
||||
ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
|
||||
ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
|
||||
|
||||
ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
|
||||
ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
|
||||
|
||||
ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
|
||||
ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
|
||||
ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
|
||||
ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
|
||||
ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
|
||||
ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
|
||||
|
||||
ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
|
||||
ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
|
||||
ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
|
||||
ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
|
||||
ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
|
||||
|
||||
ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
|
||||
ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
|
||||
ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
|
||||
ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
|
||||
ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
|
||||
|
||||
ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
|
||||
ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
|
||||
ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
|
||||
|
||||
ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
|
||||
ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
|
||||
ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
|
||||
ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
|
||||
|
||||
ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
|
||||
ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
|
||||
ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
|
||||
ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
|
||||
|
||||
ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
|
||||
ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
|
||||
ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
|
||||
ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
|
||||
|
||||
ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
|
||||
|
||||
ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
|
||||
ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
|
||||
ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
|
||||
ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
|
||||
ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
|
||||
|
||||
/* arith */
|
||||
ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
|
||||
ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
|
||||
ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
|
||||
ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
|
||||
ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
|
||||
|
||||
ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
|
||||
ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
|
||||
ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
|
||||
ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
|
||||
|
||||
ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
|
||||
ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
|
||||
ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
|
||||
ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
|
||||
|
||||
ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
|
||||
ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
|
||||
|
||||
ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
|
||||
ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
|
||||
|
||||
ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
|
||||
ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
|
||||
ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
|
||||
ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
|
||||
ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
|
||||
|
||||
ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
|
||||
ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
|
||||
ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
|
||||
ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
|
||||
|
||||
/* shifts */
|
||||
ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
|
||||
ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
|
||||
ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
|
||||
|
||||
ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
|
||||
ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
|
||||
ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
|
||||
ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
|
||||
ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
|
||||
ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
|
||||
|
||||
ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
|
||||
ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
|
||||
ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
|
||||
ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
|
||||
|
||||
ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
|
||||
ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
|
||||
ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
|
||||
ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
|
||||
|
||||
ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
|
||||
ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
|
||||
DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
|
||||
DEF_ASM_OP0(leave, 0xc9)
|
||||
DEF_ASM_OP0(ret, 0xc3)
|
||||
ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
|
||||
DEF_ASM_OP0(lret, 0xcb)
|
||||
ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
|
||||
|
||||
ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
|
||||
DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
|
||||
DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
|
||||
DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
|
||||
DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
|
||||
DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
|
||||
DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
|
||||
|
||||
/* float */
|
||||
/* specific fcomp handling */
|
||||
ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
|
||||
|
||||
ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
|
||||
ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
|
||||
ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
|
||||
ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
|
||||
ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
|
||||
ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
|
||||
ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
|
||||
ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
|
||||
ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
|
||||
ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
|
||||
ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
|
||||
|
||||
DEF_ASM_OP0(fucompp, 0xdae9)
|
||||
DEF_ASM_OP0(ftst, 0xd9e4)
|
||||
DEF_ASM_OP0(fxam, 0xd9e5)
|
||||
DEF_ASM_OP0(fld1, 0xd9e8)
|
||||
DEF_ASM_OP0(fldl2t, 0xd9e9)
|
||||
DEF_ASM_OP0(fldl2e, 0xd9ea)
|
||||
DEF_ASM_OP0(fldpi, 0xd9eb)
|
||||
DEF_ASM_OP0(fldlg2, 0xd9ec)
|
||||
DEF_ASM_OP0(fldln2, 0xd9ed)
|
||||
DEF_ASM_OP0(fldz, 0xd9ee)
|
||||
|
||||
DEF_ASM_OP0(f2xm1, 0xd9f0)
|
||||
DEF_ASM_OP0(fyl2x, 0xd9f1)
|
||||
DEF_ASM_OP0(fptan, 0xd9f2)
|
||||
DEF_ASM_OP0(fpatan, 0xd9f3)
|
||||
DEF_ASM_OP0(fxtract, 0xd9f4)
|
||||
DEF_ASM_OP0(fprem1, 0xd9f5)
|
||||
DEF_ASM_OP0(fdecstp, 0xd9f6)
|
||||
DEF_ASM_OP0(fincstp, 0xd9f7)
|
||||
DEF_ASM_OP0(fprem, 0xd9f8)
|
||||
DEF_ASM_OP0(fyl2xp1, 0xd9f9)
|
||||
DEF_ASM_OP0(fsqrt, 0xd9fa)
|
||||
DEF_ASM_OP0(fsincos, 0xd9fb)
|
||||
DEF_ASM_OP0(frndint, 0xd9fc)
|
||||
DEF_ASM_OP0(fscale, 0xd9fd)
|
||||
DEF_ASM_OP0(fsin, 0xd9fe)
|
||||
DEF_ASM_OP0(fcos, 0xd9ff)
|
||||
DEF_ASM_OP0(fchs, 0xd9e0)
|
||||
DEF_ASM_OP0(fabs, 0xd9e1)
|
||||
DEF_ASM_OP0(fninit, 0xdbe3)
|
||||
DEF_ASM_OP0(fnclex, 0xdbe2)
|
||||
DEF_ASM_OP0(fnop, 0xd9d0)
|
||||
DEF_ASM_OP0(fwait, 0x9b)
|
||||
|
||||
/* fp load */
|
||||
DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
|
||||
DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
|
||||
DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
|
||||
ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
|
||||
DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
|
||||
DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
|
||||
|
||||
/* fp store */
|
||||
DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
|
||||
DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
|
||||
DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
|
||||
ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
|
||||
DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
|
||||
|
||||
DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
|
||||
DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
|
||||
|
||||
/* exchange */
|
||||
DEF_ASM_OP0(fxch, 0xd9c9)
|
||||
ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
|
||||
|
||||
/* misc FPU */
|
||||
DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
|
||||
DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
|
||||
|
||||
DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
|
||||
DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
|
||||
DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
|
||||
DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
|
||||
DEF_ASM_OP0(fnstsw, 0xdfe0)
|
||||
ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
|
||||
ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
|
||||
DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
|
||||
ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
|
||||
ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
|
||||
DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
|
||||
DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
|
||||
DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
|
||||
DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
|
||||
DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
|
||||
DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
|
||||
DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
|
||||
DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
|
||||
DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
|
||||
DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
|
||||
DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
|
||||
|
||||
/* segments */
|
||||
DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
|
||||
DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
|
||||
DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
|
||||
DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
|
||||
ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
|
||||
DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
|
||||
DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
|
||||
DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
|
||||
DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
|
||||
DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
|
||||
DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
|
||||
|
||||
/* 486 */
|
||||
DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
|
||||
ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
|
||||
ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
|
||||
DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
|
||||
|
||||
DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
|
||||
DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
|
||||
|
||||
/* pentium */
|
||||
DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
|
||||
|
||||
/* pentium pro */
|
||||
ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
|
||||
|
||||
DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
|
||||
DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
|
||||
DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
|
||||
DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
|
||||
DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
|
||||
DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
|
||||
DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
|
||||
DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
|
||||
|
||||
DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
|
||||
DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
|
||||
DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
|
||||
DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
|
||||
|
||||
/* mmx */
|
||||
DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
|
||||
DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
|
||||
ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
|
||||
DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
|
||||
DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
|
||||
DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
|
||||
DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
|
||||
DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
|
||||
DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
|
||||
DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
|
||||
DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
|
||||
DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
|
||||
DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
|
||||
|
||||
#undef ALT
|
||||
#undef DEF_ASM_OP0
|
||||
#undef DEF_ASM_OP0L
|
||||
#undef DEF_ASM_OP1
|
||||
#undef DEF_ASM_OP2
|
||||
#undef DEF_ASM_OP3
|
1017
programs/develop/metcc/trunk/source/i386-gen.c
Normal file
1017
programs/develop/metcc/trunk/source/i386-gen.c
Normal file
File diff suppressed because it is too large
Load Diff
667
programs/develop/metcc/trunk/source/il-gen.c
Normal file
667
programs/develop/metcc/trunk/source/il-gen.c
Normal file
@ -0,0 +1,667 @@
|
||||
/*
|
||||
* CIL code generator for TCC
|
||||
*
|
||||
* Copyright (c) 2002 Fabrice Bellard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* number of available registers */
|
||||
#define NB_REGS 3
|
||||
|
||||
/* a register can belong to several classes. The classes must be
|
||||
sorted from more general to more precise (see gv2() code which does
|
||||
assumptions on it). */
|
||||
#define RC_ST 0x0001 /* any stack entry */
|
||||
#define RC_ST0 0x0002 /* top of stack */
|
||||
#define RC_ST1 0x0004 /* top - 1 */
|
||||
|
||||
#define RC_INT RC_ST
|
||||
#define RC_FLOAT RC_ST
|
||||
#define RC_IRET RC_ST0 /* function return: integer register */
|
||||
#define RC_LRET RC_ST0 /* function return: second integer register */
|
||||
#define RC_FRET RC_ST0 /* function return: float register */
|
||||
|
||||
/* pretty names for the registers */
|
||||
enum {
|
||||
REG_ST0 = 0,
|
||||
REG_ST1,
|
||||
REG_ST2,
|
||||
};
|
||||
|
||||
int reg_classes[NB_REGS] = {
|
||||
/* ST0 */ RC_ST | RC_ST0,
|
||||
/* ST1 */ RC_ST | RC_ST1,
|
||||
/* ST2 */ RC_ST,
|
||||
};
|
||||
|
||||
/* return registers for function */
|
||||
#define REG_IRET REG_ST0 /* single word int return register */
|
||||
#define REG_LRET REG_ST0 /* second word return register (for long long) */
|
||||
#define REG_FRET REG_ST0 /* float return register */
|
||||
|
||||
/* defined if function parameters must be evaluated in reverse order */
|
||||
//#define INVERT_FUNC_PARAMS
|
||||
|
||||
/* defined if structures are passed as pointers. Otherwise structures
|
||||
are directly pushed on stack. */
|
||||
//#define FUNC_STRUCT_PARAM_AS_PTR
|
||||
|
||||
/* pointer size, in bytes */
|
||||
#define PTR_SIZE 4
|
||||
|
||||
/* long double size and alignment, in bytes */
|
||||
#define LDOUBLE_SIZE 8
|
||||
#define LDOUBLE_ALIGN 8
|
||||
|
||||
/* function call context */
|
||||
typedef struct GFuncContext {
|
||||
int func_call; /* func call type (FUNC_STDCALL or FUNC_CDECL) */
|
||||
} GFuncContext;
|
||||
|
||||
/******************************************************/
|
||||
/* opcode definitions */
|
||||
|
||||
#define IL_OP_PREFIX 0xFE
|
||||
|
||||
enum ILOPCodes {
|
||||
#define OP(name, str, n) IL_OP_ ## name = n,
|
||||
#include "il-opcodes.h"
|
||||
#undef OP
|
||||
};
|
||||
|
||||
char *il_opcodes_str[] = {
|
||||
#define OP(name, str, n) [n] = str,
|
||||
#include "il-opcodes.h"
|
||||
#undef OP
|
||||
};
|
||||
|
||||
/******************************************************/
|
||||
|
||||
/* arguments variable numbers start from there */
|
||||
#define ARG_BASE 0x70000000
|
||||
|
||||
static FILE *il_outfile;
|
||||
|
||||
static void out_byte(int c)
|
||||
{
|
||||
*(char *)ind++ = c;
|
||||
}
|
||||
|
||||
static void out_le32(int c)
|
||||
{
|
||||
out_byte(c);
|
||||
out_byte(c >> 8);
|
||||
out_byte(c >> 16);
|
||||
out_byte(c >> 24);
|
||||
}
|
||||
|
||||
static void init_outfile(void)
|
||||
{
|
||||
if (!il_outfile) {
|
||||
il_outfile = stdout;
|
||||
fprintf(il_outfile,
|
||||
".assembly extern mscorlib\n"
|
||||
"{\n"
|
||||
".ver 1:0:2411:0\n"
|
||||
"}\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void out_op1(int op)
|
||||
{
|
||||
if (op & 0x100)
|
||||
out_byte(IL_OP_PREFIX);
|
||||
out_byte(op & 0xff);
|
||||
}
|
||||
|
||||
/* output an opcode with prefix */
|
||||
static void out_op(int op)
|
||||
{
|
||||
out_op1(op);
|
||||
fprintf(il_outfile, " %s\n", il_opcodes_str[op]);
|
||||
}
|
||||
|
||||
static void out_opb(int op, int c)
|
||||
{
|
||||
out_op1(op);
|
||||
out_byte(c);
|
||||
fprintf(il_outfile, " %s %d\n", il_opcodes_str[op], c);
|
||||
}
|
||||
|
||||
static void out_opi(int op, int c)
|
||||
{
|
||||
out_op1(op);
|
||||
out_le32(c);
|
||||
fprintf(il_outfile, " %s 0x%x\n", il_opcodes_str[op], c);
|
||||
}
|
||||
|
||||
/* XXX: not complete */
|
||||
static void il_type_to_str(char *buf, int buf_size,
|
||||
int t, const char *varstr)
|
||||
{
|
||||
int bt;
|
||||
Sym *s, *sa;
|
||||
char buf1[256];
|
||||
const char *tstr;
|
||||
|
||||
t = t & VT_TYPE;
|
||||
bt = t & VT_BTYPE;
|
||||
buf[0] = '\0';
|
||||
if (t & VT_UNSIGNED)
|
||||
pstrcat(buf, buf_size, "unsigned ");
|
||||
switch(bt) {
|
||||
case VT_VOID:
|
||||
tstr = "void";
|
||||
goto add_tstr;
|
||||
case VT_BOOL:
|
||||
tstr = "bool";
|
||||
goto add_tstr;
|
||||
case VT_BYTE:
|
||||
tstr = "int8";
|
||||
goto add_tstr;
|
||||
case VT_SHORT:
|
||||
tstr = "int16";
|
||||
goto add_tstr;
|
||||
case VT_ENUM:
|
||||
case VT_INT:
|
||||
case VT_LONG:
|
||||
tstr = "int32";
|
||||
goto add_tstr;
|
||||
case VT_LLONG:
|
||||
tstr = "int64";
|
||||
goto add_tstr;
|
||||
case VT_FLOAT:
|
||||
tstr = "float32";
|
||||
goto add_tstr;
|
||||
case VT_DOUBLE:
|
||||
case VT_LDOUBLE:
|
||||
tstr = "float64";
|
||||
add_tstr:
|
||||
pstrcat(buf, buf_size, tstr);
|
||||
break;
|
||||
case VT_STRUCT:
|
||||
error("structures not handled yet");
|
||||
break;
|
||||
case VT_FUNC:
|
||||
s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
|
||||
il_type_to_str(buf, buf_size, s->t, varstr);
|
||||
pstrcat(buf, buf_size, "(");
|
||||
sa = s->next;
|
||||
while (sa != NULL) {
|
||||
il_type_to_str(buf1, sizeof(buf1), sa->t, NULL);
|
||||
pstrcat(buf, buf_size, buf1);
|
||||
sa = sa->next;
|
||||
if (sa)
|
||||
pstrcat(buf, buf_size, ", ");
|
||||
}
|
||||
pstrcat(buf, buf_size, ")");
|
||||
goto no_var;
|
||||
case VT_PTR:
|
||||
s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
|
||||
pstrcpy(buf1, sizeof(buf1), "*");
|
||||
if (varstr)
|
||||
pstrcat(buf1, sizeof(buf1), varstr);
|
||||
il_type_to_str(buf, buf_size, s->t, buf1);
|
||||
goto no_var;
|
||||
}
|
||||
if (varstr) {
|
||||
pstrcat(buf, buf_size, " ");
|
||||
pstrcat(buf, buf_size, varstr);
|
||||
}
|
||||
no_var: ;
|
||||
}
|
||||
|
||||
|
||||
/* patch relocation entry with value 'val' */
|
||||
void greloc_patch1(Reloc *p, int val)
|
||||
{
|
||||
}
|
||||
|
||||
/* output a symbol and patch all calls to it */
|
||||
void gsym_addr(t, a)
|
||||
{
|
||||
}
|
||||
|
||||
/* output jump and return symbol */
|
||||
static int out_opj(int op, int c)
|
||||
{
|
||||
out_op1(op);
|
||||
out_le32(0);
|
||||
if (c == 0) {
|
||||
c = ind - (int)cur_text_section->data;
|
||||
}
|
||||
fprintf(il_outfile, " %s L%d\n", il_opcodes_str[op], c);
|
||||
return c;
|
||||
}
|
||||
|
||||
void gsym(int t)
|
||||
{
|
||||
fprintf(il_outfile, "L%d:\n", t);
|
||||
}
|
||||
|
||||
/* load 'r' from value 'sv' */
|
||||
void load(int r, SValue *sv)
|
||||
{
|
||||
int v, fc, ft;
|
||||
|
||||
v = sv->r & VT_VALMASK;
|
||||
fc = sv->c.i;
|
||||
ft = sv->t;
|
||||
|
||||
if (sv->r & VT_LVAL) {
|
||||
if (v == VT_LOCAL) {
|
||||
if (fc >= ARG_BASE) {
|
||||
fc -= ARG_BASE;
|
||||
if (fc >= 0 && fc <= 4) {
|
||||
out_op(IL_OP_LDARG_0 + fc);
|
||||
} else if (fc <= 0xff) {
|
||||
out_opb(IL_OP_LDARG_S, fc);
|
||||
} else {
|
||||
out_opi(IL_OP_LDARG, fc);
|
||||
}
|
||||
} else {
|
||||
if (fc >= 0 && fc <= 4) {
|
||||
out_op(IL_OP_LDLOC_0 + fc);
|
||||
} else if (fc <= 0xff) {
|
||||
out_opb(IL_OP_LDLOC_S, fc);
|
||||
} else {
|
||||
out_opi(IL_OP_LDLOC, fc);
|
||||
}
|
||||
}
|
||||
} else if (v == VT_CONST) {
|
||||
/* XXX: handle globals */
|
||||
out_opi(IL_OP_LDSFLD, 0);
|
||||
} else {
|
||||
if ((ft & VT_BTYPE) == VT_FLOAT) {
|
||||
out_op(IL_OP_LDIND_R4);
|
||||
} else if ((ft & VT_BTYPE) == VT_DOUBLE) {
|
||||
out_op(IL_OP_LDIND_R8);
|
||||
} else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
|
||||
out_op(IL_OP_LDIND_R8);
|
||||
} else if ((ft & VT_TYPE) == VT_BYTE)
|
||||
out_op(IL_OP_LDIND_I1);
|
||||
else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED))
|
||||
out_op(IL_OP_LDIND_U1);
|
||||
else if ((ft & VT_TYPE) == VT_SHORT)
|
||||
out_op(IL_OP_LDIND_I2);
|
||||
else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED))
|
||||
out_op(IL_OP_LDIND_U2);
|
||||
else
|
||||
out_op(IL_OP_LDIND_I4);
|
||||
}
|
||||
} else {
|
||||
if (v == VT_CONST) {
|
||||
/* XXX: handle globals */
|
||||
if (fc >= -1 && fc <= 8) {
|
||||
out_op(IL_OP_LDC_I4_M1 + fc + 1);
|
||||
} else {
|
||||
out_opi(IL_OP_LDC_I4, fc);
|
||||
}
|
||||
} else if (v == VT_LOCAL) {
|
||||
if (fc >= ARG_BASE) {
|
||||
fc -= ARG_BASE;
|
||||
if (fc <= 0xff) {
|
||||
out_opb(IL_OP_LDARGA_S, fc);
|
||||
} else {
|
||||
out_opi(IL_OP_LDARGA, fc);
|
||||
}
|
||||
} else {
|
||||
if (fc <= 0xff) {
|
||||
out_opb(IL_OP_LDLOCA_S, fc);
|
||||
} else {
|
||||
out_opi(IL_OP_LDLOCA, fc);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* XXX: do it */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* store register 'r' in lvalue 'v' */
|
||||
void store(int r, SValue *sv)
|
||||
{
|
||||
int v, fc, ft;
|
||||
|
||||
v = sv->r & VT_VALMASK;
|
||||
fc = sv->c.i;
|
||||
ft = sv->t;
|
||||
if (v == VT_LOCAL) {
|
||||
if (fc >= ARG_BASE) {
|
||||
fc -= ARG_BASE;
|
||||
/* XXX: check IL arg store semantics */
|
||||
if (fc <= 0xff) {
|
||||
out_opb(IL_OP_STARG_S, fc);
|
||||
} else {
|
||||
out_opi(IL_OP_STARG, fc);
|
||||
}
|
||||
} else {
|
||||
if (fc >= 0 && fc <= 4) {
|
||||
out_op(IL_OP_STLOC_0 + fc);
|
||||
} else if (fc <= 0xff) {
|
||||
out_opb(IL_OP_STLOC_S, fc);
|
||||
} else {
|
||||
out_opi(IL_OP_STLOC, fc);
|
||||
}
|
||||
}
|
||||
} else if (v == VT_CONST) {
|
||||
/* XXX: handle globals */
|
||||
out_opi(IL_OP_STSFLD, 0);
|
||||
} else {
|
||||
if ((ft & VT_BTYPE) == VT_FLOAT)
|
||||
out_op(IL_OP_STIND_R4);
|
||||
else if ((ft & VT_BTYPE) == VT_DOUBLE)
|
||||
out_op(IL_OP_STIND_R8);
|
||||
else if ((ft & VT_BTYPE) == VT_LDOUBLE)
|
||||
out_op(IL_OP_STIND_R8);
|
||||
else if ((ft & VT_BTYPE) == VT_BYTE)
|
||||
out_op(IL_OP_STIND_I1);
|
||||
else if ((ft & VT_BTYPE) == VT_SHORT)
|
||||
out_op(IL_OP_STIND_I2);
|
||||
else
|
||||
out_op(IL_OP_STIND_I4);
|
||||
}
|
||||
}
|
||||
|
||||
/* start function call and return function call context */
|
||||
void gfunc_start(GFuncContext *c, int func_call)
|
||||
{
|
||||
c->func_call = func_call;
|
||||
}
|
||||
|
||||
/* push function parameter which is in (vtop->t, vtop->c). Stack entry
|
||||
is then popped. */
|
||||
void gfunc_param(GFuncContext *c)
|
||||
{
|
||||
if ((vtop->t & VT_BTYPE) == VT_STRUCT) {
|
||||
error("structures passed as value not handled yet");
|
||||
} else {
|
||||
/* simply push on stack */
|
||||
gv(RC_ST0);
|
||||
}
|
||||
vtop--;
|
||||
}
|
||||
|
||||
/* generate function call with address in (vtop->t, vtop->c) and free function
|
||||
context. Stack entry is popped */
|
||||
void gfunc_call(GFuncContext *c)
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
||||
/* XXX: more info needed from tcc */
|
||||
il_type_to_str(buf, sizeof(buf), vtop->t, "xxx");
|
||||
fprintf(il_outfile, " call %s\n", buf);
|
||||
} else {
|
||||
/* indirect call */
|
||||
gv(RC_INT);
|
||||
il_type_to_str(buf, sizeof(buf), vtop->t, NULL);
|
||||
fprintf(il_outfile, " calli %s\n", buf);
|
||||
}
|
||||
vtop--;
|
||||
}
|
||||
|
||||
/* generate function prolog of type 't' */
|
||||
void gfunc_prolog(int t)
|
||||
{
|
||||
int addr, u, func_call;
|
||||
Sym *sym;
|
||||
char buf[1024];
|
||||
|
||||
init_outfile();
|
||||
|
||||
/* XXX: pass function name to gfunc_prolog */
|
||||
il_type_to_str(buf, sizeof(buf), t, funcname);
|
||||
fprintf(il_outfile, ".method static %s il managed\n", buf);
|
||||
fprintf(il_outfile, "{\n");
|
||||
/* XXX: cannot do better now */
|
||||
fprintf(il_outfile, " .maxstack %d\n", NB_REGS);
|
||||
fprintf(il_outfile, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n");
|
||||
|
||||
if (!strcmp(funcname, "main"))
|
||||
fprintf(il_outfile, " .entrypoint\n");
|
||||
|
||||
sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
|
||||
func_call = sym->r;
|
||||
|
||||
addr = ARG_BASE;
|
||||
/* if the function returns a structure, then add an
|
||||
implicit pointer parameter */
|
||||
func_vt = sym->t;
|
||||
if ((func_vt & VT_BTYPE) == VT_STRUCT) {
|
||||
func_vc = addr;
|
||||
addr++;
|
||||
}
|
||||
/* define parameters */
|
||||
while ((sym = sym->next) != NULL) {
|
||||
u = sym->t;
|
||||
sym_push(sym->v & ~SYM_FIELD, u,
|
||||
VT_LOCAL | VT_LVAL, addr);
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* generate function epilog */
|
||||
void gfunc_epilog(void)
|
||||
{
|
||||
out_op(IL_OP_RET);
|
||||
fprintf(il_outfile, "}\n\n");
|
||||
}
|
||||
|
||||
/* generate a jump to a label */
|
||||
int gjmp(int t)
|
||||
{
|
||||
return out_opj(IL_OP_BR, t);
|
||||
}
|
||||
|
||||
/* generate a jump to a fixed address */
|
||||
void gjmp_addr(int a)
|
||||
{
|
||||
/* XXX: handle syms */
|
||||
out_opi(IL_OP_BR, a);
|
||||
}
|
||||
|
||||
/* generate a test. set 'inv' to invert test. Stack entry is popped */
|
||||
int gtst(int inv, int t)
|
||||
{
|
||||
int v, *p, c;
|
||||
|
||||
v = vtop->r & VT_VALMASK;
|
||||
if (v == VT_CMP) {
|
||||
c = vtop->c.i ^ inv;
|
||||
switch(c) {
|
||||
case TOK_EQ:
|
||||
c = IL_OP_BEQ;
|
||||
break;
|
||||
case TOK_NE:
|
||||
c = IL_OP_BNE_UN;
|
||||
break;
|
||||
case TOK_LT:
|
||||
c = IL_OP_BLT;
|
||||
break;
|
||||
case TOK_LE:
|
||||
c = IL_OP_BLE;
|
||||
break;
|
||||
case TOK_GT:
|
||||
c = IL_OP_BGT;
|
||||
break;
|
||||
case TOK_GE:
|
||||
c = IL_OP_BGE;
|
||||
break;
|
||||
case TOK_ULT:
|
||||
c = IL_OP_BLT_UN;
|
||||
break;
|
||||
case TOK_ULE:
|
||||
c = IL_OP_BLE_UN;
|
||||
break;
|
||||
case TOK_UGT:
|
||||
c = IL_OP_BGT_UN;
|
||||
break;
|
||||
case TOK_UGE:
|
||||
c = IL_OP_BGE_UN;
|
||||
break;
|
||||
}
|
||||
t = out_opj(c, t);
|
||||
} else if (v == VT_JMP || v == VT_JMPI) {
|
||||
/* && or || optimization */
|
||||
if ((v & 1) == inv) {
|
||||
/* insert vtop->c jump list in t */
|
||||
p = &vtop->c.i;
|
||||
while (*p != 0)
|
||||
p = (int *)*p;
|
||||
*p = t;
|
||||
t = vtop->c.i;
|
||||
} else {
|
||||
t = gjmp(t);
|
||||
gsym(vtop->c.i);
|
||||
}
|
||||
} else {
|
||||
if (is_float(vtop->t)) {
|
||||
vpushi(0);
|
||||
gen_op(TOK_NE);
|
||||
}
|
||||
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) {
|
||||
/* constant jmp optimization */
|
||||
if ((vtop->c.i != 0) != inv)
|
||||
t = gjmp(t);
|
||||
} else {
|
||||
v = gv(RC_INT);
|
||||
t = out_opj(IL_OP_BRTRUE - inv, t);
|
||||
}
|
||||
}
|
||||
vtop--;
|
||||
return t;
|
||||
}
|
||||
|
||||
/* generate an integer binary operation */
|
||||
void gen_opi(int op)
|
||||
{
|
||||
gv2(RC_ST1, RC_ST0);
|
||||
switch(op) {
|
||||
case '+':
|
||||
out_op(IL_OP_ADD);
|
||||
goto std_op;
|
||||
case '-':
|
||||
out_op(IL_OP_SUB);
|
||||
goto std_op;
|
||||
case '&':
|
||||
out_op(IL_OP_AND);
|
||||
goto std_op;
|
||||
case '^':
|
||||
out_op(IL_OP_XOR);
|
||||
goto std_op;
|
||||
case '|':
|
||||
out_op(IL_OP_OR);
|
||||
goto std_op;
|
||||
case '*':
|
||||
out_op(IL_OP_MUL);
|
||||
goto std_op;
|
||||
case TOK_SHL:
|
||||
out_op(IL_OP_SHL);
|
||||
goto std_op;
|
||||
case TOK_SHR:
|
||||
out_op(IL_OP_SHR_UN);
|
||||
goto std_op;
|
||||
case TOK_SAR:
|
||||
out_op(IL_OP_SHR);
|
||||
goto std_op;
|
||||
case '/':
|
||||
case TOK_PDIV:
|
||||
out_op(IL_OP_DIV);
|
||||
goto std_op;
|
||||
case TOK_UDIV:
|
||||
out_op(IL_OP_DIV_UN);
|
||||
goto std_op;
|
||||
case '%':
|
||||
out_op(IL_OP_REM);
|
||||
goto std_op;
|
||||
case TOK_UMOD:
|
||||
out_op(IL_OP_REM_UN);
|
||||
std_op:
|
||||
vtop--;
|
||||
vtop[0].r = REG_ST0;
|
||||
break;
|
||||
case TOK_EQ:
|
||||
case TOK_NE:
|
||||
case TOK_LT:
|
||||
case TOK_LE:
|
||||
case TOK_GT:
|
||||
case TOK_GE:
|
||||
case TOK_ULT:
|
||||
case TOK_ULE:
|
||||
case TOK_UGT:
|
||||
case TOK_UGE:
|
||||
vtop--;
|
||||
vtop[0].r = VT_CMP;
|
||||
vtop[0].c.i = op;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* generate a floating point operation 'v = t1 op t2' instruction. The
|
||||
two operands are guaranted to have the same floating point type */
|
||||
void gen_opf(int op)
|
||||
{
|
||||
/* same as integer */
|
||||
gen_opi(op);
|
||||
}
|
||||
|
||||
/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
|
||||
and 'long long' cases. */
|
||||
void gen_cvt_itof(int t)
|
||||
{
|
||||
gv(RC_ST0);
|
||||
if (t == VT_FLOAT)
|
||||
out_op(IL_OP_CONV_R4);
|
||||
else
|
||||
out_op(IL_OP_CONV_R8);
|
||||
}
|
||||
|
||||
/* convert fp to int 't' type */
|
||||
/* XXX: handle long long case */
|
||||
void gen_cvt_ftoi(int t)
|
||||
{
|
||||
gv(RC_ST0);
|
||||
switch(t) {
|
||||
case VT_INT | VT_UNSIGNED:
|
||||
out_op(IL_OP_CONV_U4);
|
||||
break;
|
||||
case VT_LLONG:
|
||||
out_op(IL_OP_CONV_I8);
|
||||
break;
|
||||
case VT_LLONG | VT_UNSIGNED:
|
||||
out_op(IL_OP_CONV_U8);
|
||||
break;
|
||||
default:
|
||||
out_op(IL_OP_CONV_I4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* convert from one floating point type to another */
|
||||
void gen_cvt_ftof(int t)
|
||||
{
|
||||
gv(RC_ST0);
|
||||
if (t == VT_FLOAT) {
|
||||
out_op(IL_OP_CONV_R4);
|
||||
} else {
|
||||
out_op(IL_OP_CONV_R8);
|
||||
}
|
||||
}
|
||||
|
||||
/* end of CIL code generator */
|
||||
/*************************************************************/
|
||||
|
251
programs/develop/metcc/trunk/source/il-opcodes.h
Normal file
251
programs/develop/metcc/trunk/source/il-opcodes.h
Normal file
@ -0,0 +1,251 @@
|
||||
/*
|
||||
* CIL opcode definition
|
||||
*
|
||||
* Copyright (c) 2002 Fabrice Bellard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
OP(NOP, "nop", 0x00)
|
||||
OP(BREAK, "break", 0x01)
|
||||
OP(LDARG_0, "ldarg.0", 0x02)
|
||||
OP(LDARG_1, "ldarg.1", 0x03)
|
||||
OP(LDARG_2, "ldarg.2", 0x04)
|
||||
OP(LDARG_3, "ldarg.3", 0x05)
|
||||
OP(LDLOC_0, "ldloc.0", 0x06)
|
||||
OP(LDLOC_1, "ldloc.1", 0x07)
|
||||
OP(LDLOC_2, "ldloc.2", 0x08)
|
||||
OP(LDLOC_3, "ldloc.3", 0x09)
|
||||
OP(STLOC_0, "stloc.0", 0x0a)
|
||||
OP(STLOC_1, "stloc.1", 0x0b)
|
||||
OP(STLOC_2, "stloc.2", 0x0c)
|
||||
OP(STLOC_3, "stloc.3", 0x0d)
|
||||
OP(LDARG_S, "ldarg.s", 0x0e)
|
||||
OP(LDARGA_S, "ldarga.s", 0x0f)
|
||||
OP(STARG_S, "starg.s", 0x10)
|
||||
OP(LDLOC_S, "ldloc.s", 0x11)
|
||||
OP(LDLOCA_S, "ldloca.s", 0x12)
|
||||
OP(STLOC_S, "stloc.s", 0x13)
|
||||
OP(LDNULL, "ldnull", 0x14)
|
||||
OP(LDC_I4_M1, "ldc.i4.m1", 0x15)
|
||||
OP(LDC_I4_0, "ldc.i4.0", 0x16)
|
||||
OP(LDC_I4_1, "ldc.i4.1", 0x17)
|
||||
OP(LDC_I4_2, "ldc.i4.2", 0x18)
|
||||
OP(LDC_I4_3, "ldc.i4.3", 0x19)
|
||||
OP(LDC_I4_4, "ldc.i4.4", 0x1a)
|
||||
OP(LDC_I4_5, "ldc.i4.5", 0x1b)
|
||||
OP(LDC_I4_6, "ldc.i4.6", 0x1c)
|
||||
OP(LDC_I4_7, "ldc.i4.7", 0x1d)
|
||||
OP(LDC_I4_8, "ldc.i4.8", 0x1e)
|
||||
OP(LDC_I4_S, "ldc.i4.s", 0x1f)
|
||||
OP(LDC_I4, "ldc.i4", 0x20)
|
||||
OP(LDC_I8, "ldc.i8", 0x21)
|
||||
OP(LDC_R4, "ldc.r4", 0x22)
|
||||
OP(LDC_R8, "ldc.r8", 0x23)
|
||||
OP(LDPTR, "ldptr", 0x24)
|
||||
OP(DUP, "dup", 0x25)
|
||||
OP(POP, "pop", 0x26)
|
||||
OP(JMP, "jmp", 0x27)
|
||||
OP(CALL, "call", 0x28)
|
||||
OP(CALLI, "calli", 0x29)
|
||||
OP(RET, "ret", 0x2a)
|
||||
OP(BR_S, "br.s", 0x2b)
|
||||
OP(BRFALSE_S, "brfalse.s", 0x2c)
|
||||
OP(BRTRUE_S, "brtrue.s", 0x2d)
|
||||
OP(BEQ_S, "beq.s", 0x2e)
|
||||
OP(BGE_S, "bge.s", 0x2f)
|
||||
OP(BGT_S, "bgt.s", 0x30)
|
||||
OP(BLE_S, "ble.s", 0x31)
|
||||
OP(BLT_S, "blt.s", 0x32)
|
||||
OP(BNE_UN_S, "bne.un.s", 0x33)
|
||||
OP(BGE_UN_S, "bge.un.s", 0x34)
|
||||
OP(BGT_UN_S, "bgt.un.s", 0x35)
|
||||
OP(BLE_UN_S, "ble.un.s", 0x36)
|
||||
OP(BLT_UN_S, "blt.un.s", 0x37)
|
||||
OP(BR, "br", 0x38)
|
||||
OP(BRFALSE, "brfalse", 0x39)
|
||||
OP(BRTRUE, "brtrue", 0x3a)
|
||||
OP(BEQ, "beq", 0x3b)
|
||||
OP(BGE, "bge", 0x3c)
|
||||
OP(BGT, "bgt", 0x3d)
|
||||
OP(BLE, "ble", 0x3e)
|
||||
OP(BLT, "blt", 0x3f)
|
||||
OP(BNE_UN, "bne.un", 0x40)
|
||||
OP(BGE_UN, "bge.un", 0x41)
|
||||
OP(BGT_UN, "bgt.un", 0x42)
|
||||
OP(BLE_UN, "ble.un", 0x43)
|
||||
OP(BLT_UN, "blt.un", 0x44)
|
||||
OP(SWITCH, "switch", 0x45)
|
||||
OP(LDIND_I1, "ldind.i1", 0x46)
|
||||
OP(LDIND_U1, "ldind.u1", 0x47)
|
||||
OP(LDIND_I2, "ldind.i2", 0x48)
|
||||
OP(LDIND_U2, "ldind.u2", 0x49)
|
||||
OP(LDIND_I4, "ldind.i4", 0x4a)
|
||||
OP(LDIND_U4, "ldind.u4", 0x4b)
|
||||
OP(LDIND_I8, "ldind.i8", 0x4c)
|
||||
OP(LDIND_I, "ldind.i", 0x4d)
|
||||
OP(LDIND_R4, "ldind.r4", 0x4e)
|
||||
OP(LDIND_R8, "ldind.r8", 0x4f)
|
||||
OP(LDIND_REF, "ldind.ref", 0x50)
|
||||
OP(STIND_REF, "stind.ref", 0x51)
|
||||
OP(STIND_I1, "stind.i1", 0x52)
|
||||
OP(STIND_I2, "stind.i2", 0x53)
|
||||
OP(STIND_I4, "stind.i4", 0x54)
|
||||
OP(STIND_I8, "stind.i8", 0x55)
|
||||
OP(STIND_R4, "stind.r4", 0x56)
|
||||
OP(STIND_R8, "stind.r8", 0x57)
|
||||
OP(ADD, "add", 0x58)
|
||||
OP(SUB, "sub", 0x59)
|
||||
OP(MUL, "mul", 0x5a)
|
||||
OP(DIV, "div", 0x5b)
|
||||
OP(DIV_UN, "div.un", 0x5c)
|
||||
OP(REM, "rem", 0x5d)
|
||||
OP(REM_UN, "rem.un", 0x5e)
|
||||
OP(AND, "and", 0x5f)
|
||||
OP(OR, "or", 0x60)
|
||||
OP(XOR, "xor", 0x61)
|
||||
OP(SHL, "shl", 0x62)
|
||||
OP(SHR, "shr", 0x63)
|
||||
OP(SHR_UN, "shr.un", 0x64)
|
||||
OP(NEG, "neg", 0x65)
|
||||
OP(NOT, "not", 0x66)
|
||||
OP(CONV_I1, "conv.i1", 0x67)
|
||||
OP(CONV_I2, "conv.i2", 0x68)
|
||||
OP(CONV_I4, "conv.i4", 0x69)
|
||||
OP(CONV_I8, "conv.i8", 0x6a)
|
||||
OP(CONV_R4, "conv.r4", 0x6b)
|
||||
OP(CONV_R8, "conv.r8", 0x6c)
|
||||
OP(CONV_U4, "conv.u4", 0x6d)
|
||||
OP(CONV_U8, "conv.u8", 0x6e)
|
||||
OP(CALLVIRT, "callvirt", 0x6f)
|
||||
OP(CPOBJ, "cpobj", 0x70)
|
||||
OP(LDOBJ, "ldobj", 0x71)
|
||||
OP(LDSTR, "ldstr", 0x72)
|
||||
OP(NEWOBJ, "newobj", 0x73)
|
||||
OP(CASTCLASS, "castclass", 0x74)
|
||||
OP(ISINST, "isinst", 0x75)
|
||||
OP(CONV_R_UN, "conv.r.un", 0x76)
|
||||
OP(ANN_DATA_S, "ann.data.s", 0x77)
|
||||
OP(UNBOX, "unbox", 0x79)
|
||||
OP(THROW, "throw", 0x7a)
|
||||
OP(LDFLD, "ldfld", 0x7b)
|
||||
OP(LDFLDA, "ldflda", 0x7c)
|
||||
OP(STFLD, "stfld", 0x7d)
|
||||
OP(LDSFLD, "ldsfld", 0x7e)
|
||||
OP(LDSFLDA, "ldsflda", 0x7f)
|
||||
OP(STSFLD, "stsfld", 0x80)
|
||||
OP(STOBJ, "stobj", 0x81)
|
||||
OP(CONV_OVF_I1_UN, "conv.ovf.i1.un", 0x82)
|
||||
OP(CONV_OVF_I2_UN, "conv.ovf.i2.un", 0x83)
|
||||
OP(CONV_OVF_I4_UN, "conv.ovf.i4.un", 0x84)
|
||||
OP(CONV_OVF_I8_UN, "conv.ovf.i8.un", 0x85)
|
||||
OP(CONV_OVF_U1_UN, "conv.ovf.u1.un", 0x86)
|
||||
OP(CONV_OVF_U2_UN, "conv.ovf.u2.un", 0x87)
|
||||
OP(CONV_OVF_U4_UN, "conv.ovf.u4.un", 0x88)
|
||||
OP(CONV_OVF_U8_UN, "conv.ovf.u8.un", 0x89)
|
||||
OP(CONV_OVF_I_UN, "conv.ovf.i.un", 0x8a)
|
||||
OP(CONV_OVF_U_UN, "conv.ovf.u.un", 0x8b)
|
||||
OP(BOX, "box", 0x8c)
|
||||
OP(NEWARR, "newarr", 0x8d)
|
||||
OP(LDLEN, "ldlen", 0x8e)
|
||||
OP(LDELEMA, "ldelema", 0x8f)
|
||||
OP(LDELEM_I1, "ldelem.i1", 0x90)
|
||||
OP(LDELEM_U1, "ldelem.u1", 0x91)
|
||||
OP(LDELEM_I2, "ldelem.i2", 0x92)
|
||||
OP(LDELEM_U2, "ldelem.u2", 0x93)
|
||||
OP(LDELEM_I4, "ldelem.i4", 0x94)
|
||||
OP(LDELEM_U4, "ldelem.u4", 0x95)
|
||||
OP(LDELEM_I8, "ldelem.i8", 0x96)
|
||||
OP(LDELEM_I, "ldelem.i", 0x97)
|
||||
OP(LDELEM_R4, "ldelem.r4", 0x98)
|
||||
OP(LDELEM_R8, "ldelem.r8", 0x99)
|
||||
OP(LDELEM_REF, "ldelem.ref", 0x9a)
|
||||
OP(STELEM_I, "stelem.i", 0x9b)
|
||||
OP(STELEM_I1, "stelem.i1", 0x9c)
|
||||
OP(STELEM_I2, "stelem.i2", 0x9d)
|
||||
OP(STELEM_I4, "stelem.i4", 0x9e)
|
||||
OP(STELEM_I8, "stelem.i8", 0x9f)
|
||||
OP(STELEM_R4, "stelem.r4", 0xa0)
|
||||
OP(STELEM_R8, "stelem.r8", 0xa1)
|
||||
OP(STELEM_REF, "stelem.ref", 0xa2)
|
||||
OP(CONV_OVF_I1, "conv.ovf.i1", 0xb3)
|
||||
OP(CONV_OVF_U1, "conv.ovf.u1", 0xb4)
|
||||
OP(CONV_OVF_I2, "conv.ovf.i2", 0xb5)
|
||||
OP(CONV_OVF_U2, "conv.ovf.u2", 0xb6)
|
||||
OP(CONV_OVF_I4, "conv.ovf.i4", 0xb7)
|
||||
OP(CONV_OVF_U4, "conv.ovf.u4", 0xb8)
|
||||
OP(CONV_OVF_I8, "conv.ovf.i8", 0xb9)
|
||||
OP(CONV_OVF_U8, "conv.ovf.u8", 0xba)
|
||||
OP(REFANYVAL, "refanyval", 0xc2)
|
||||
OP(CKFINITE, "ckfinite", 0xc3)
|
||||
OP(MKREFANY, "mkrefany", 0xc6)
|
||||
OP(ANN_CALL, "ann.call", 0xc7)
|
||||
OP(ANN_CATCH, "ann.catch", 0xc8)
|
||||
OP(ANN_DEAD, "ann.dead", 0xc9)
|
||||
OP(ANN_HOISTED, "ann.hoisted", 0xca)
|
||||
OP(ANN_HOISTED_CALL, "ann.hoisted.call", 0xcb)
|
||||
OP(ANN_LAB, "ann.lab", 0xcc)
|
||||
OP(ANN_DEF, "ann.def", 0xcd)
|
||||
OP(ANN_REF_S, "ann.ref.s", 0xce)
|
||||
OP(ANN_PHI, "ann.phi", 0xcf)
|
||||
OP(LDTOKEN, "ldtoken", 0xd0)
|
||||
OP(CONV_U2, "conv.u2", 0xd1)
|
||||
OP(CONV_U1, "conv.u1", 0xd2)
|
||||
OP(CONV_I, "conv.i", 0xd3)
|
||||
OP(CONV_OVF_I, "conv.ovf.i", 0xd4)
|
||||
OP(CONV_OVF_U, "conv.ovf.u", 0xd5)
|
||||
OP(ADD_OVF, "add.ovf", 0xd6)
|
||||
OP(ADD_OVF_UN, "add.ovf.un", 0xd7)
|
||||
OP(MUL_OVF, "mul.ovf", 0xd8)
|
||||
OP(MUL_OVF_UN, "mul.ovf.un", 0xd9)
|
||||
OP(SUB_OVF, "sub.ovf", 0xda)
|
||||
OP(SUB_OVF_UN, "sub.ovf.un", 0xdb)
|
||||
OP(ENDFINALLY, "endfinally", 0xdc)
|
||||
OP(LEAVE, "leave", 0xdd)
|
||||
OP(LEAVE_S, "leave.s", 0xde)
|
||||
OP(STIND_I, "stind.i", 0xdf)
|
||||
OP(CONV_U, "conv.u", 0xe0)
|
||||
|
||||
/* prefix instructions. we use an opcode >= 256 to ease coding */
|
||||
|
||||
OP(ARGLIST, "arglist", 0x100)
|
||||
OP(CEQ, "ceq", 0x101)
|
||||
OP(CGT, "cgt", 0x102)
|
||||
OP(CGT_UN, "cgt.un", 0x103)
|
||||
OP(CLT, "clt", 0x104)
|
||||
OP(CLT_UN, "clt.un", 0x105)
|
||||
OP(LDFTN, "ldftn", 0x106)
|
||||
OP(LDVIRTFTN, "ldvirtftn", 0x107)
|
||||
OP(JMPI, "jmpi", 0x108)
|
||||
OP(LDARG, "ldarg", 0x109)
|
||||
OP(LDARGA, "ldarga", 0x10a)
|
||||
OP(STARG, "starg", 0x10b)
|
||||
OP(LDLOC, "ldloc", 0x10c)
|
||||
OP(LDLOCA, "ldloca", 0x10d)
|
||||
OP(STLOC, "stloc", 0x10e)
|
||||
OP(LOCALLOC, "localloc", 0x10f)
|
||||
OP(ENDFILTER, "endfilter", 0x111)
|
||||
OP(UNALIGNED, "unaligned", 0x112)
|
||||
OP(VOLATILE, "volatile", 0x113)
|
||||
OP(TAIL, "tail", 0x114)
|
||||
OP(INITOBJ, "initobj", 0x115)
|
||||
OP(ANN_LIVE, "ann.live", 0x116)
|
||||
OP(CPBLK, "cpblk", 0x117)
|
||||
OP(INITBLK, "initblk", 0x118)
|
||||
OP(ANN_REF, "ann.ref", 0x119)
|
||||
OP(RETHROW, "rethrow", 0x11a)
|
||||
OP(SIZEOF, "sizeof", 0x11c)
|
||||
OP(REFANYTYPE, "refanytype", 0x11d)
|
||||
OP(ANN_DATA, "ann.data", 0x122)
|
||||
OP(ANN_ARG, "ann.arg", 0x123)
|
97
programs/develop/metcc/trunk/source/libtcc.h
Normal file
97
programs/develop/metcc/trunk/source/libtcc.h
Normal file
@ -0,0 +1,97 @@
|
||||
#ifndef LIBTCC_H
|
||||
#define LIBTCC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct TCCState;
|
||||
|
||||
typedef struct TCCState TCCState;
|
||||
|
||||
/* create a new TCC compilation context */
|
||||
TCCState *tcc_new(void);
|
||||
|
||||
/* free a TCC compilation context */
|
||||
void tcc_delete(TCCState *s);
|
||||
|
||||
/* add debug information in the generated code */
|
||||
void tcc_enable_debug(TCCState *s);
|
||||
|
||||
/* set error/warning display callback */
|
||||
void tcc_set_error_func(TCCState *s, void *error_opaque,
|
||||
void (*error_func)(void *opaque, const char *msg));
|
||||
|
||||
/* set/reset a warning */
|
||||
int tcc_set_warning(TCCState *s, const char *warning_name, int value);
|
||||
|
||||
/*****************************/
|
||||
/* preprocessor */
|
||||
|
||||
/* add include path */
|
||||
int tcc_add_include_path(TCCState *s, const char *pathname);
|
||||
|
||||
/* add in system include path */
|
||||
int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
|
||||
|
||||
/* define preprocessor symbol 'sym'. Can put optional value */
|
||||
void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
|
||||
|
||||
/* undefine preprocess symbol 'sym' */
|
||||
void tcc_undefine_symbol(TCCState *s, const char *sym);
|
||||
|
||||
/*****************************/
|
||||
/* compiling */
|
||||
|
||||
/* add a file (either a C file, dll, an object, a library or an ld
|
||||
script). Return -1 if error. */
|
||||
int tcc_add_file(TCCState *s, const char *filename);
|
||||
|
||||
/* compile a string containing a C source. Return non zero if
|
||||
error. */
|
||||
int tcc_compile_string(TCCState *s, const char *buf);
|
||||
|
||||
/*****************************/
|
||||
/* linking commands */
|
||||
|
||||
/* set output type. MUST BE CALLED before any compilation */
|
||||
#define TCC_OUTPUT_MEMORY 0 /* output will be ran in memory (no
|
||||
output file) (default) */
|
||||
#define TCC_OUTPUT_EXE 1 /* executable file */
|
||||
#define TCC_OUTPUT_DLL 2 /* dynamic library */
|
||||
#define TCC_OUTPUT_OBJ 3 /* object file */
|
||||
int tcc_set_output_type(TCCState *s, int output_type);
|
||||
|
||||
#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */
|
||||
#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
|
||||
#define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */
|
||||
|
||||
/* equivalent to -Lpath option */
|
||||
int tcc_add_library_path(TCCState *s, const char *pathname);
|
||||
|
||||
/* the library name is the same as the argument of the '-l' option */
|
||||
int tcc_add_library(TCCState *s, const char *libraryname);
|
||||
|
||||
/* add a symbol to the compiled program */
|
||||
int tcc_add_symbol(TCCState *s, const char *name, unsigned long val);
|
||||
|
||||
/* output an executable, library or object file. DO NOT call
|
||||
tcc_relocate() before. */
|
||||
int tcc_output_file(TCCState *s, const char *filename);
|
||||
|
||||
/* link and run main() function and return its value. DO NOT call
|
||||
tcc_relocate() before. */
|
||||
int tcc_run(TCCState *s, int argc, char **argv);
|
||||
|
||||
/* do all relocations (needed before using tcc_get_symbol()). Return
|
||||
non zero if link error. */
|
||||
int tcc_relocate(TCCState *s);
|
||||
|
||||
/* return symbol value. return 0 if OK, -1 if symbol not found */
|
||||
int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
602
programs/develop/metcc/trunk/source/libtcc1.c
Normal file
602
programs/develop/metcc/trunk/source/libtcc1.c
Normal file
@ -0,0 +1,602 @@
|
||||
/* TCC runtime library.
|
||||
Parts of this code are (c) 2002 Fabrice Bellard
|
||||
|
||||
Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file into combinations with other programs,
|
||||
and to distribute those combinations without any restriction coming
|
||||
from the use of this file. (The General Public License restrictions
|
||||
do apply in other respects; for example, they cover modification of
|
||||
the file, and distribution when not linked into a combine
|
||||
executable.)
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#define W_TYPE_SIZE 32
|
||||
#define BITS_PER_UNIT 8
|
||||
|
||||
typedef int Wtype;
|
||||
typedef unsigned int UWtype;
|
||||
typedef unsigned int USItype;
|
||||
typedef long long DWtype;
|
||||
typedef unsigned long long UDWtype;
|
||||
|
||||
struct DWstruct {
|
||||
Wtype low, high;
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct DWstruct s;
|
||||
DWtype ll;
|
||||
} DWunion;
|
||||
|
||||
typedef long double XFtype;
|
||||
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
||||
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
||||
|
||||
/* the following deal with IEEE single-precision numbers */
|
||||
#define EXCESS 126
|
||||
#define SIGNBIT 0x80000000
|
||||
#define HIDDEN (1 << 23)
|
||||
#define SIGN(fp) ((fp) & SIGNBIT)
|
||||
#define EXP(fp) (((fp) >> 23) & 0xFF)
|
||||
#define MANT(fp) (((fp) & 0x7FFFFF) | HIDDEN)
|
||||
#define PACK(s,e,m) ((s) | ((e) << 23) | (m))
|
||||
|
||||
/* the following deal with IEEE double-precision numbers */
|
||||
#define EXCESSD 1022
|
||||
#define HIDDEND (1 << 20)
|
||||
#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
|
||||
#define SIGND(fp) ((fp.l.upper) & SIGNBIT)
|
||||
#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
|
||||
(fp.l.lower >> 22))
|
||||
#define HIDDEND_LL ((long long)1 << 52)
|
||||
#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
|
||||
#define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m))
|
||||
|
||||
/* the following deal with x86 long double-precision numbers */
|
||||
#define EXCESSLD 16382
|
||||
#define EXPLD(fp) (fp.l.upper & 0x7fff)
|
||||
#define SIGNLD(fp) ((fp.l.upper) & 0x8000)
|
||||
|
||||
/* only for x86 */
|
||||
union ldouble_long {
|
||||
long double ld;
|
||||
struct {
|
||||
unsigned long long lower;
|
||||
unsigned short upper;
|
||||
} l;
|
||||
};
|
||||
|
||||
union double_long {
|
||||
double d;
|
||||
#if 1
|
||||
struct {
|
||||
unsigned long lower;
|
||||
long upper;
|
||||
} l;
|
||||
#else
|
||||
struct {
|
||||
long upper;
|
||||
unsigned long lower;
|
||||
} l;
|
||||
#endif
|
||||
long long ll;
|
||||
};
|
||||
|
||||
union float_long {
|
||||
float f;
|
||||
long l;
|
||||
};
|
||||
|
||||
/* XXX: use gcc/tcc intrinsic ? */
|
||||
#if defined(__i386__)
|
||||
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
|
||||
__asm__ ("subl %5,%1\n\tsbbl %3,%0" \
|
||||
: "=r" ((USItype) (sh)), \
|
||||
"=&r" ((USItype) (sl)) \
|
||||
: "0" ((USItype) (ah)), \
|
||||
"g" ((USItype) (bh)), \
|
||||
"1" ((USItype) (al)), \
|
||||
"g" ((USItype) (bl)))
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
__asm__ ("mull %3" \
|
||||
: "=a" ((USItype) (w0)), \
|
||||
"=d" ((USItype) (w1)) \
|
||||
: "%0" ((USItype) (u)), \
|
||||
"rm" ((USItype) (v)))
|
||||
#define udiv_qrnnd(q, r, n1, n0, dv) \
|
||||
__asm__ ("divl %4" \
|
||||
: "=a" ((USItype) (q)), \
|
||||
"=d" ((USItype) (r)) \
|
||||
: "0" ((USItype) (n0)), \
|
||||
"1" ((USItype) (n1)), \
|
||||
"rm" ((USItype) (dv)))
|
||||
#define count_leading_zeros(count, x) \
|
||||
do { \
|
||||
USItype __cbtmp; \
|
||||
__asm__ ("bsrl %1,%0" \
|
||||
: "=r" (__cbtmp) : "rm" ((USItype) (x))); \
|
||||
(count) = __cbtmp ^ 31; \
|
||||
} while (0)
|
||||
#else
|
||||
#error unsupported CPU type
|
||||
#endif
|
||||
|
||||
/* most of this code is taken from libgcc2.c from gcc */
|
||||
|
||||
static UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
|
||||
{
|
||||
DWunion ww;
|
||||
DWunion nn, dd;
|
||||
DWunion rr;
|
||||
UWtype d0, d1, n0, n1, n2;
|
||||
UWtype q0, q1;
|
||||
UWtype b, bm;
|
||||
|
||||
nn.ll = n;
|
||||
dd.ll = d;
|
||||
|
||||
d0 = dd.s.low;
|
||||
d1 = dd.s.high;
|
||||
n0 = nn.s.low;
|
||||
n1 = nn.s.high;
|
||||
|
||||
#if !UDIV_NEEDS_NORMALIZATION
|
||||
if (d1 == 0)
|
||||
{
|
||||
if (d0 > n1)
|
||||
{
|
||||
/* 0q = nn / 0D */
|
||||
|
||||
udiv_qrnnd (q0, n0, n1, n0, d0);
|
||||
q1 = 0;
|
||||
|
||||
/* Remainder in n0. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* qq = NN / 0d */
|
||||
|
||||
if (d0 == 0)
|
||||
d0 = 1 / d0; /* Divide intentionally by zero. */
|
||||
|
||||
udiv_qrnnd (q1, n1, 0, n1, d0);
|
||||
udiv_qrnnd (q0, n0, n1, n0, d0);
|
||||
|
||||
/* Remainder in n0. */
|
||||
}
|
||||
|
||||
if (rp != 0)
|
||||
{
|
||||
rr.s.low = n0;
|
||||
rr.s.high = 0;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* UDIV_NEEDS_NORMALIZATION */
|
||||
|
||||
if (d1 == 0)
|
||||
{
|
||||
if (d0 > n1)
|
||||
{
|
||||
/* 0q = nn / 0D */
|
||||
|
||||
count_leading_zeros (bm, d0);
|
||||
|
||||
if (bm != 0)
|
||||
{
|
||||
/* Normalize, i.e. make the most significant bit of the
|
||||
denominator set. */
|
||||
|
||||
d0 = d0 << bm;
|
||||
n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
|
||||
n0 = n0 << bm;
|
||||
}
|
||||
|
||||
udiv_qrnnd (q0, n0, n1, n0, d0);
|
||||
q1 = 0;
|
||||
|
||||
/* Remainder in n0 >> bm. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* qq = NN / 0d */
|
||||
|
||||
if (d0 == 0)
|
||||
d0 = 1 / d0; /* Divide intentionally by zero. */
|
||||
|
||||
count_leading_zeros (bm, d0);
|
||||
|
||||
if (bm == 0)
|
||||
{
|
||||
/* From (n1 >= d0) /\ (the most significant bit of d0 is set),
|
||||
conclude (the most significant bit of n1 is set) /\ (the
|
||||
leading quotient digit q1 = 1).
|
||||
|
||||
This special case is necessary, not an optimization.
|
||||
(Shifts counts of W_TYPE_SIZE are undefined.) */
|
||||
|
||||
n1 -= d0;
|
||||
q1 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Normalize. */
|
||||
|
||||
b = W_TYPE_SIZE - bm;
|
||||
|
||||
d0 = d0 << bm;
|
||||
n2 = n1 >> b;
|
||||
n1 = (n1 << bm) | (n0 >> b);
|
||||
n0 = n0 << bm;
|
||||
|
||||
udiv_qrnnd (q1, n1, n2, n1, d0);
|
||||
}
|
||||
|
||||
/* n1 != d0... */
|
||||
|
||||
udiv_qrnnd (q0, n0, n1, n0, d0);
|
||||
|
||||
/* Remainder in n0 >> bm. */
|
||||
}
|
||||
|
||||
if (rp != 0)
|
||||
{
|
||||
rr.s.low = n0 >> bm;
|
||||
rr.s.high = 0;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
}
|
||||
#endif /* UDIV_NEEDS_NORMALIZATION */
|
||||
|
||||
else
|
||||
{
|
||||
if (d1 > n1)
|
||||
{
|
||||
/* 00 = nn / DD */
|
||||
|
||||
q0 = 0;
|
||||
q1 = 0;
|
||||
|
||||
/* Remainder in n1n0. */
|
||||
if (rp != 0)
|
||||
{
|
||||
rr.s.low = n0;
|
||||
rr.s.high = n1;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 0q = NN / dd */
|
||||
|
||||
count_leading_zeros (bm, d1);
|
||||
if (bm == 0)
|
||||
{
|
||||
/* From (n1 >= d1) /\ (the most significant bit of d1 is set),
|
||||
conclude (the most significant bit of n1 is set) /\ (the
|
||||
quotient digit q0 = 0 or 1).
|
||||
|
||||
This special case is necessary, not an optimization. */
|
||||
|
||||
/* The condition on the next line takes advantage of that
|
||||
n1 >= d1 (true due to program flow). */
|
||||
if (n1 > d1 || n0 >= d0)
|
||||
{
|
||||
q0 = 1;
|
||||
sub_ddmmss (n1, n0, n1, n0, d1, d0);
|
||||
}
|
||||
else
|
||||
q0 = 0;
|
||||
|
||||
q1 = 0;
|
||||
|
||||
if (rp != 0)
|
||||
{
|
||||
rr.s.low = n0;
|
||||
rr.s.high = n1;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UWtype m1, m0;
|
||||
/* Normalize. */
|
||||
|
||||
b = W_TYPE_SIZE - bm;
|
||||
|
||||
d1 = (d1 << bm) | (d0 >> b);
|
||||
d0 = d0 << bm;
|
||||
n2 = n1 >> b;
|
||||
n1 = (n1 << bm) | (n0 >> b);
|
||||
n0 = n0 << bm;
|
||||
|
||||
udiv_qrnnd (q0, n1, n2, n1, d1);
|
||||
umul_ppmm (m1, m0, q0, d0);
|
||||
|
||||
if (m1 > n1 || (m1 == n1 && m0 > n0))
|
||||
{
|
||||
q0--;
|
||||
sub_ddmmss (m1, m0, m1, m0, d1, d0);
|
||||
}
|
||||
|
||||
q1 = 0;
|
||||
|
||||
/* Remainder in (n1n0 - m1m0) >> bm. */
|
||||
if (rp != 0)
|
||||
{
|
||||
sub_ddmmss (n1, n0, n1, n0, m1, m0);
|
||||
rr.s.low = (n1 << b) | (n0 >> bm);
|
||||
rr.s.high = n1 >> bm;
|
||||
*rp = rr.ll;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ww.s.low = q0;
|
||||
ww.s.high = q1;
|
||||
return ww.ll;
|
||||
}
|
||||
|
||||
#define __negdi2(a) (-(a))
|
||||
|
||||
long long __divdi3(long long u, long long v)
|
||||
{
|
||||
int c = 0;
|
||||
DWunion uu, vv;
|
||||
DWtype w;
|
||||
|
||||
uu.ll = u;
|
||||
vv.ll = v;
|
||||
|
||||
if (uu.s.high < 0) {
|
||||
c = ~c;
|
||||
uu.ll = __negdi2 (uu.ll);
|
||||
}
|
||||
if (vv.s.high < 0) {
|
||||
c = ~c;
|
||||
vv.ll = __negdi2 (vv.ll);
|
||||
}
|
||||
w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
|
||||
if (c)
|
||||
w = __negdi2 (w);
|
||||
return w;
|
||||
}
|
||||
|
||||
long long __moddi3(long long u, long long v)
|
||||
{
|
||||
int c = 0;
|
||||
DWunion uu, vv;
|
||||
DWtype w;
|
||||
|
||||
uu.ll = u;
|
||||
vv.ll = v;
|
||||
|
||||
if (uu.s.high < 0) {
|
||||
c = ~c;
|
||||
uu.ll = __negdi2 (uu.ll);
|
||||
}
|
||||
if (vv.s.high < 0)
|
||||
vv.ll = __negdi2 (vv.ll);
|
||||
|
||||
__udivmoddi4 (uu.ll, vv.ll, &w);
|
||||
if (c)
|
||||
w = __negdi2 (w);
|
||||
return w;
|
||||
}
|
||||
|
||||
unsigned long long __udivdi3(unsigned long long u, unsigned long long v)
|
||||
{
|
||||
return __udivmoddi4 (u, v, (UDWtype *) 0);
|
||||
}
|
||||
|
||||
unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
|
||||
{
|
||||
UDWtype w;
|
||||
|
||||
__udivmoddi4 (u, v, &w);
|
||||
return w;
|
||||
}
|
||||
|
||||
/* XXX: fix tcc's code generator to do this instead */
|
||||
long long __sardi3(long long a, int b)
|
||||
{
|
||||
#ifdef __TINYC__
|
||||
DWunion u;
|
||||
u.ll = a;
|
||||
if (b >= 32) {
|
||||
u.s.low = u.s.high >> (b - 32);
|
||||
u.s.high = u.s.high >> 31;
|
||||
} else if (b != 0) {
|
||||
u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
|
||||
u.s.high = u.s.high >> b;
|
||||
}
|
||||
return u.ll;
|
||||
#else
|
||||
return a >> b;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* XXX: fix tcc's code generator to do this instead */
|
||||
unsigned long long __shrdi3(unsigned long long a, int b)
|
||||
{
|
||||
#ifdef __TINYC__
|
||||
DWunion u;
|
||||
u.ll = a;
|
||||
if (b >= 32) {
|
||||
u.s.low = (unsigned)u.s.high >> (b - 32);
|
||||
u.s.high = 0;
|
||||
} else if (b != 0) {
|
||||
u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
|
||||
u.s.high = (unsigned)u.s.high >> b;
|
||||
}
|
||||
return u.ll;
|
||||
#else
|
||||
return a >> b;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* XXX: fix tcc's code generator to do this instead */
|
||||
long long __shldi3(long long a, int b)
|
||||
{
|
||||
#ifdef __TINYC__
|
||||
DWunion u;
|
||||
u.ll = a;
|
||||
if (b >= 32) {
|
||||
u.s.high = (unsigned)u.s.low << (b - 32);
|
||||
u.s.low = 0;
|
||||
} else if (b != 0) {
|
||||
u.s.high = ((unsigned)u.s.high << b) | (u.s.low >> (32 - b));
|
||||
u.s.low = (unsigned)u.s.low << b;
|
||||
}
|
||||
return u.ll;
|
||||
#else
|
||||
return a << b;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__i386__)
|
||||
/* FPU control word for rounding to nearest mode */
|
||||
unsigned short __tcc_fpu_control = 0x137f;
|
||||
/* FPU control word for round to zero mode for int conversion */
|
||||
unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00;
|
||||
#endif
|
||||
|
||||
/* XXX: fix tcc's code generator to do this instead */
|
||||
float __ulltof(unsigned long long a)
|
||||
{
|
||||
DWunion uu;
|
||||
XFtype r;
|
||||
|
||||
uu.ll = a;
|
||||
if (uu.s.high >= 0) {
|
||||
return (float)uu.ll;
|
||||
} else {
|
||||
r = (XFtype)uu.ll;
|
||||
r += 18446744073709551616.0;
|
||||
return (float)r;
|
||||
}
|
||||
}
|
||||
|
||||
double __ulltod(unsigned long long a)
|
||||
{
|
||||
DWunion uu;
|
||||
XFtype r;
|
||||
|
||||
uu.ll = a;
|
||||
if (uu.s.high >= 0) {
|
||||
return (double)uu.ll;
|
||||
} else {
|
||||
r = (XFtype)uu.ll;
|
||||
r += 18446744073709551616.0;
|
||||
return (double)r;
|
||||
}
|
||||
}
|
||||
|
||||
long double __ulltold(unsigned long long a)
|
||||
{
|
||||
DWunion uu;
|
||||
XFtype r;
|
||||
|
||||
uu.ll = a;
|
||||
if (uu.s.high >= 0) {
|
||||
return (long double)uu.ll;
|
||||
} else {
|
||||
r = (XFtype)uu.ll;
|
||||
r += 18446744073709551616.0;
|
||||
return (long double)r;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long long __fixunssfdi (float a1)
|
||||
{
|
||||
register union float_long fl1;
|
||||
register int exp;
|
||||
register unsigned long l;
|
||||
|
||||
fl1.f = a1;
|
||||
|
||||
if (fl1.l == 0)
|
||||
return (0);
|
||||
|
||||
exp = EXP (fl1.l) - EXCESS - 24;
|
||||
|
||||
l = MANT(fl1.l);
|
||||
if (exp >= 41)
|
||||
return (unsigned long long)-1;
|
||||
else if (exp >= 0)
|
||||
return (unsigned long long)l << exp;
|
||||
else if (exp >= -23)
|
||||
return l >> -exp;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long __fixunsdfdi (double a1)
|
||||
{
|
||||
register union double_long dl1;
|
||||
register int exp;
|
||||
register unsigned long long l;
|
||||
|
||||
dl1.d = a1;
|
||||
|
||||
if (dl1.ll == 0)
|
||||
return (0);
|
||||
|
||||
exp = EXPD (dl1) - EXCESSD - 53;
|
||||
|
||||
l = MANTD_LL(dl1);
|
||||
|
||||
if (exp >= 12)
|
||||
return (unsigned long long)-1;
|
||||
else if (exp >= 0)
|
||||
return l << exp;
|
||||
else if (exp >= -52)
|
||||
return l >> -exp;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long __fixunsxfdi (long double a1)
|
||||
{
|
||||
register union ldouble_long dl1;
|
||||
register int exp;
|
||||
register unsigned long long l;
|
||||
|
||||
dl1.ld = a1;
|
||||
|
||||
if (dl1.l.lower == 0 && dl1.l.upper == 0)
|
||||
return (0);
|
||||
|
||||
exp = EXPLD (dl1) - EXCESSLD - 64;
|
||||
|
||||
l = dl1.l.lower;
|
||||
|
||||
if (exp > 0)
|
||||
return (unsigned long long)-1;
|
||||
else if (exp >= -63)
|
||||
return l >> -exp;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
65
programs/develop/metcc/trunk/source/libtcc_test.c
Normal file
65
programs/develop/metcc/trunk/source/libtcc_test.c
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Simple Test program for libtcc
|
||||
*
|
||||
* libtcc can be useful to use tcc as a "backend" for a code generator.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libtcc.h"
|
||||
|
||||
/* this function is called by the generated code */
|
||||
int add(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
char my_program[] =
|
||||
"int fib(int n)\n"
|
||||
"{\n"
|
||||
" if (n <= 2)\n"
|
||||
" return 1;\n"
|
||||
" else\n"
|
||||
" return fib(n-1) + fib(n-2);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"int foo(int n)\n"
|
||||
"{\n"
|
||||
" printf(\"Hello World!\\n\");\n"
|
||||
" printf(\"fib(%d) = %d\\n\", n, fib(n));\n"
|
||||
" printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"
|
||||
" return 0;\n"
|
||||
"}\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
TCCState *s;
|
||||
int (*func)(int);
|
||||
unsigned long val;
|
||||
|
||||
s = tcc_new();
|
||||
if (!s) {
|
||||
fprintf(stderr, "Could not create tcc state\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* MUST BE CALLED before any compilation or file loading */
|
||||
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
|
||||
|
||||
tcc_compile_string(s, my_program);
|
||||
|
||||
/* as a test, we add a symbol that the compiled program can be
|
||||
linked with. You can have a similar result by opening a dll
|
||||
with tcc_add_dll(() and using its symbols directly. */
|
||||
tcc_add_symbol(s, "add", (unsigned long)&add);
|
||||
|
||||
tcc_relocate(s);
|
||||
|
||||
tcc_get_symbol(s, &val, "foo");
|
||||
func = (void *)val;
|
||||
|
||||
func(32);
|
||||
|
||||
tcc_delete(s);
|
||||
return 0;
|
||||
}
|
234
programs/develop/metcc/trunk/source/stab.def
Normal file
234
programs/develop/metcc/trunk/source/stab.def
Normal file
@ -0,0 +1,234 @@
|
||||
/* Table of DBX symbol codes for the GNU system.
|
||||
Copyright (C) 1988, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This contains contribution from Cygnus Support. */
|
||||
|
||||
/* Global variable. Only the name is significant.
|
||||
To find the address, look in the corresponding external symbol. */
|
||||
__define_stab (N_GSYM, 0x20, "GSYM")
|
||||
|
||||
/* Function name for BSD Fortran. Only the name is significant.
|
||||
To find the address, look in the corresponding external symbol. */
|
||||
__define_stab (N_FNAME, 0x22, "FNAME")
|
||||
|
||||
/* Function name or text-segment variable for C. Value is its address.
|
||||
Desc is supposedly starting line number, but GCC doesn't set it
|
||||
and DBX seems not to miss it. */
|
||||
__define_stab (N_FUN, 0x24, "FUN")
|
||||
|
||||
/* Data-segment variable with internal linkage. Value is its address.
|
||||
"Static Sym". */
|
||||
__define_stab (N_STSYM, 0x26, "STSYM")
|
||||
|
||||
/* BSS-segment variable with internal linkage. Value is its address. */
|
||||
__define_stab (N_LCSYM, 0x28, "LCSYM")
|
||||
|
||||
/* Name of main routine. Only the name is significant.
|
||||
This is not used in C. */
|
||||
__define_stab (N_MAIN, 0x2a, "MAIN")
|
||||
|
||||
/* Global symbol in Pascal.
|
||||
Supposedly the value is its line number; I'm skeptical. */
|
||||
__define_stab (N_PC, 0x30, "PC")
|
||||
|
||||
/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */
|
||||
__define_stab (N_NSYMS, 0x32, "NSYMS")
|
||||
|
||||
/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */
|
||||
__define_stab (N_NOMAP, 0x34, "NOMAP")
|
||||
|
||||
/* New stab from Solaris. I don't know what it means, but it
|
||||
don't seem to contain useful information. */
|
||||
__define_stab (N_OBJ, 0x38, "OBJ")
|
||||
|
||||
/* New stab from Solaris. I don't know what it means, but it
|
||||
don't seem to contain useful information. Possibly related to the
|
||||
optimization flags used in this module. */
|
||||
__define_stab (N_OPT, 0x3c, "OPT")
|
||||
|
||||
/* Register variable. Value is number of register. */
|
||||
__define_stab (N_RSYM, 0x40, "RSYM")
|
||||
|
||||
/* Modula-2 compilation unit. Can someone say what info it contains? */
|
||||
__define_stab (N_M2C, 0x42, "M2C")
|
||||
|
||||
/* Line number in text segment. Desc is the line number;
|
||||
value is corresponding address. */
|
||||
__define_stab (N_SLINE, 0x44, "SLINE")
|
||||
|
||||
/* Similar, for data segment. */
|
||||
__define_stab (N_DSLINE, 0x46, "DSLINE")
|
||||
|
||||
/* Similar, for bss segment. */
|
||||
__define_stab (N_BSLINE, 0x48, "BSLINE")
|
||||
|
||||
/* Sun's source-code browser stabs. ?? Don't know what the fields are.
|
||||
Supposedly the field is "path to associated .cb file". THIS VALUE
|
||||
OVERLAPS WITH N_BSLINE! */
|
||||
__define_stab (N_BROWS, 0x48, "BROWS")
|
||||
|
||||
/* GNU Modula-2 definition module dependency. Value is the modification time
|
||||
of the definition file. Other is non-zero if it is imported with the
|
||||
GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there
|
||||
are enough empty fields? */
|
||||
__define_stab(N_DEFD, 0x4a, "DEFD")
|
||||
|
||||
/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2
|
||||
and one is for C++. Still,... */
|
||||
/* GNU C++ exception variable. Name is variable name. */
|
||||
__define_stab (N_EHDECL, 0x50, "EHDECL")
|
||||
/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */
|
||||
__define_stab (N_MOD2, 0x50, "MOD2")
|
||||
|
||||
/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if
|
||||
this entry is immediately followed by a CAUGHT stab saying what exception
|
||||
was caught. Multiple CAUGHT stabs means that multiple exceptions
|
||||
can be caught here. If Desc is 0, it means all exceptions are caught
|
||||
here. */
|
||||
__define_stab (N_CATCH, 0x54, "CATCH")
|
||||
|
||||
/* Structure or union element. Value is offset in the structure. */
|
||||
__define_stab (N_SSYM, 0x60, "SSYM")
|
||||
|
||||
/* Name of main source file.
|
||||
Value is starting text address of the compilation. */
|
||||
__define_stab (N_SO, 0x64, "SO")
|
||||
|
||||
/* Automatic variable in the stack. Value is offset from frame pointer.
|
||||
Also used for type descriptions. */
|
||||
__define_stab (N_LSYM, 0x80, "LSYM")
|
||||
|
||||
/* Beginning of an include file. Only Sun uses this.
|
||||
In an object file, only the name is significant.
|
||||
The Sun linker puts data into some of the other fields. */
|
||||
__define_stab (N_BINCL, 0x82, "BINCL")
|
||||
|
||||
/* Name of sub-source file (#include file).
|
||||
Value is starting text address of the compilation. */
|
||||
__define_stab (N_SOL, 0x84, "SOL")
|
||||
|
||||
/* Parameter variable. Value is offset from argument pointer.
|
||||
(On most machines the argument pointer is the same as the frame pointer. */
|
||||
__define_stab (N_PSYM, 0xa0, "PSYM")
|
||||
|
||||
/* End of an include file. No name.
|
||||
This and N_BINCL act as brackets around the file's output.
|
||||
In an object file, there is no significant data in this entry.
|
||||
The Sun linker puts data into some of the fields. */
|
||||
__define_stab (N_EINCL, 0xa2, "EINCL")
|
||||
|
||||
/* Alternate entry point. Value is its address. */
|
||||
__define_stab (N_ENTRY, 0xa4, "ENTRY")
|
||||
|
||||
/* Beginning of lexical block.
|
||||
The desc is the nesting level in lexical blocks.
|
||||
The value is the address of the start of the text for the block.
|
||||
The variables declared inside the block *precede* the N_LBRAC symbol. */
|
||||
__define_stab (N_LBRAC, 0xc0, "LBRAC")
|
||||
|
||||
/* Place holder for deleted include file. Replaces a N_BINCL and everything
|
||||
up to the corresponding N_EINCL. The Sun linker generates these when
|
||||
it finds multiple identical copies of the symbols from an include file.
|
||||
This appears only in output from the Sun linker. */
|
||||
__define_stab (N_EXCL, 0xc2, "EXCL")
|
||||
|
||||
/* Modula-2 scope information. Can someone say what info it contains? */
|
||||
__define_stab (N_SCOPE, 0xc4, "SCOPE")
|
||||
|
||||
/* End of a lexical block. Desc matches the N_LBRAC's desc.
|
||||
The value is the address of the end of the text for the block. */
|
||||
__define_stab (N_RBRAC, 0xe0, "RBRAC")
|
||||
|
||||
/* Begin named common block. Only the name is significant. */
|
||||
__define_stab (N_BCOMM, 0xe2, "BCOMM")
|
||||
|
||||
/* End named common block. Only the name is significant
|
||||
(and it should match the N_BCOMM). */
|
||||
__define_stab (N_ECOMM, 0xe4, "ECOMM")
|
||||
|
||||
/* End common (local name): value is address.
|
||||
I'm not sure how this is used. */
|
||||
__define_stab (N_ECOML, 0xe8, "ECOML")
|
||||
|
||||
/* These STAB's are used on Gould systems for Non-Base register symbols
|
||||
or something like that. FIXME. I have assigned the values at random
|
||||
since I don't have a Gould here. Fixups from Gould folk welcome... */
|
||||
__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
|
||||
__define_stab (N_NBDATA, 0xF2, "NBDATA")
|
||||
__define_stab (N_NBBSS, 0xF4, "NBBSS")
|
||||
__define_stab (N_NBSTS, 0xF6, "NBSTS")
|
||||
__define_stab (N_NBLCS, 0xF8, "NBLCS")
|
||||
|
||||
/* Second symbol entry containing a length-value for the preceding entry.
|
||||
The value is the length. */
|
||||
__define_stab (N_LENG, 0xfe, "LENG")
|
||||
|
||||
/* The above information, in matrix format.
|
||||
|
||||
STAB MATRIX
|
||||
_________________________________________________
|
||||
| 00 - 1F are not dbx stab symbols |
|
||||
| In most cases, the low bit is the EXTernal bit|
|
||||
|
||||
| 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA |
|
||||
| 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT |
|
||||
|
||||
| 08 BSS | 0A INDR | 0C FN_SEQ | 0E |
|
||||
| 09 |EXT | 0B | 0D | 0F |
|
||||
|
||||
| 10 | 12 COMM | 14 SETA | 16 SETT |
|
||||
| 11 | 13 | 15 | 17 |
|
||||
|
||||
| 18 SETD | 1A SETB | 1C SETV | 1E WARNING|
|
||||
| 19 | 1B | 1D | 1F FN |
|
||||
|
||||
|_______________________________________________|
|
||||
| Debug entries with bit 01 set are unused. |
|
||||
| 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM |
|
||||
| 28 LCSYM | 2A MAIN | 2C | 2E |
|
||||
| 30 PC | 32 NSYMS | 34 NOMAP | 36 |
|
||||
| 38 OBJ | 3A | 3C OPT | 3E |
|
||||
| 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE |
|
||||
| 48 BSLINE*| 4A DEFD | 4C | 4E |
|
||||
| 50 EHDECL*| 52 | 54 CATCH | 56 |
|
||||
| 58 | 5A | 5C | 5E |
|
||||
| 60 SSYM | 62 | 64 SO | 66 |
|
||||
| 68 | 6A | 6C | 6E |
|
||||
| 70 | 72 | 74 | 76 |
|
||||
| 78 | 7A | 7C | 7E |
|
||||
| 80 LSYM | 82 BINCL | 84 SOL | 86 |
|
||||
| 88 | 8A | 8C | 8E |
|
||||
| 90 | 92 | 94 | 96 |
|
||||
| 98 | 9A | 9C | 9E |
|
||||
| A0 PSYM | A2 EINCL | A4 ENTRY | A6 |
|
||||
| A8 | AA | AC | AE |
|
||||
| B0 | B2 | B4 | B6 |
|
||||
| B8 | BA | BC | BE |
|
||||
| C0 LBRAC | C2 EXCL | C4 SCOPE | C6 |
|
||||
| C8 | CA | CC | CE |
|
||||
| D0 | D2 | D4 | D6 |
|
||||
| D8 | DA | DC | DE |
|
||||
| E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 |
|
||||
| E8 ECOML | EA | EC | EE |
|
||||
| F0 | F2 | F4 | F6 |
|
||||
| F8 | FA | FC | FE LENG |
|
||||
+-----------------------------------------------+
|
||||
* 50 EHDECL is also MOD2.
|
||||
* 48 BSLINE is also BROWS.
|
||||
*/
|
17
programs/develop/metcc/trunk/source/stab.h
Normal file
17
programs/develop/metcc/trunk/source/stab.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef __GNU_STAB__
|
||||
|
||||
/* Indicate the GNU stab.h is in use. */
|
||||
|
||||
#define __GNU_STAB__
|
||||
|
||||
#define __define_stab(NAME, CODE, STRING) NAME=CODE,
|
||||
|
||||
enum __stab_debug_code
|
||||
{
|
||||
#include "stab.def"
|
||||
LAST_UNUSED_STAB_CODE
|
||||
};
|
||||
|
||||
#undef __define_stab
|
||||
|
||||
#endif /* __GNU_STAB_ */
|
15
programs/develop/metcc/trunk/source/stdarg.h
Normal file
15
programs/develop/metcc/trunk/source/stdarg.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef _STDARG_H
|
||||
#define _STDARG_H
|
||||
|
||||
typedef char *va_list;
|
||||
|
||||
/* only correct for i386 */
|
||||
#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)
|
||||
#define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3)))
|
||||
#define va_end(ap)
|
||||
|
||||
/* fix a buggy dependency on GCC in libio.h */
|
||||
typedef va_list __gnuc_va_list;
|
||||
#define _VA_LIST_DEFINED
|
||||
|
||||
#endif
|
10
programs/develop/metcc/trunk/source/stdbool.h
Normal file
10
programs/develop/metcc/trunk/source/stdbool.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef _STDBOOL_H
|
||||
#define _STDBOOL_H
|
||||
|
||||
/* ISOC99 boolean */
|
||||
|
||||
#define bool _Bool
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#endif /* _STDBOOL_H */
|
21
programs/develop/metcc/trunk/source/stddef.h
Normal file
21
programs/develop/metcc/trunk/source/stddef.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef _STDDEF_H
|
||||
#define _STDDEF_H
|
||||
|
||||
#define NULL ((void *)0)
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
typedef __WCHAR_TYPE__ wchar_t;
|
||||
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
||||
#define offsetof(type, field) ((size_t) &((type *)0)->field)
|
||||
|
||||
/* need to do that because of glibc 2.1 bug (should have a way to test
|
||||
presence of 'long long' without __GNUC__, or TCC should define
|
||||
__GNUC__ ? */
|
||||
#if !defined(__int8_t_defined) && !defined(__dietlibc__)
|
||||
#define __int8_t_defined
|
||||
typedef char int8_t;
|
||||
typedef short int int16_t;
|
||||
typedef int int32_t;
|
||||
typedef long long int int64_t;
|
||||
#endif
|
||||
|
||||
#endif
|
1809
programs/develop/metcc/trunk/source/tcc-doc.html
Normal file
1809
programs/develop/metcc/trunk/source/tcc-doc.html
Normal file
File diff suppressed because it is too large
Load Diff
10708
programs/develop/metcc/trunk/source/tcc.c
Normal file
10708
programs/develop/metcc/trunk/source/tcc.c
Normal file
File diff suppressed because it is too large
Load Diff
1019
programs/develop/metcc/trunk/source/tccasm.c
Normal file
1019
programs/develop/metcc/trunk/source/tccasm.c
Normal file
File diff suppressed because it is too large
Load Diff
955
programs/develop/metcc/trunk/source/tcccoff.c
Normal file
955
programs/develop/metcc/trunk/source/tcccoff.c
Normal file
@ -0,0 +1,955 @@
|
||||
/*
|
||||
* COFF file handling for TCC
|
||||
*
|
||||
* Copyright (c) 2003, 2004 TK
|
||||
* Copyright (c) 2004 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "coff.h"
|
||||
|
||||
#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
|
||||
#define MAX_STR_TABLE 1000000
|
||||
AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */
|
||||
|
||||
SCNHDR section_header[MAXNSCNS];
|
||||
|
||||
#define MAX_FUNCS 1000
|
||||
#define MAX_FUNC_NAME_LENGTH 128
|
||||
|
||||
int nFuncs;
|
||||
char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
|
||||
char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
|
||||
int LineNoFilePtr[MAX_FUNCS];
|
||||
int EndAddress[MAX_FUNCS];
|
||||
int LastLineNo[MAX_FUNCS];
|
||||
int FuncEntries[MAX_FUNCS];
|
||||
|
||||
BOOL OutputTheSection(Section * sect);
|
||||
short int GetCoffFlags(const char *s);
|
||||
void SortSymbolTable(void);
|
||||
Section *FindSection(TCCState * s1, const char *sname);
|
||||
|
||||
int C67_main_entry_point;
|
||||
|
||||
int FindCoffSymbolIndex(const char *func_name);
|
||||
int nb_syms;
|
||||
|
||||
typedef struct {
|
||||
long tag;
|
||||
long size;
|
||||
long fileptr;
|
||||
long nextsym;
|
||||
short int dummy;
|
||||
} AUXFUNC;
|
||||
|
||||
typedef struct {
|
||||
long regmask;
|
||||
unsigned short lineno;
|
||||
unsigned short nentries;
|
||||
int localframe;
|
||||
int nextentry;
|
||||
short int dummy;
|
||||
} AUXBF;
|
||||
|
||||
typedef struct {
|
||||
long dummy;
|
||||
unsigned short lineno;
|
||||
unsigned short dummy1;
|
||||
int dummy2;
|
||||
int dummy3;
|
||||
unsigned short dummy4;
|
||||
} AUXEF;
|
||||
|
||||
int tcc_output_coff(TCCState *s1, FILE *f)
|
||||
{
|
||||
Section *tcc_sect;
|
||||
SCNHDR *coff_sec;
|
||||
int file_pointer;
|
||||
char *Coff_str_table, *pCoff_str_table;
|
||||
int CoffTextSectionNo, coff_nb_syms;
|
||||
FILHDR file_hdr; /* FILE HEADER STRUCTURE */
|
||||
Section *stext, *sdata, *sbss;
|
||||
int i, NSectionsToOutput = 0;
|
||||
|
||||
stext = FindSection(s1, ".text");
|
||||
sdata = FindSection(s1, ".data");
|
||||
sbss = FindSection(s1, ".bss");
|
||||
|
||||
nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
|
||||
coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
|
||||
|
||||
file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */
|
||||
file_hdr.f_timdat = 0; /* time & date stamp */
|
||||
file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */
|
||||
file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */
|
||||
file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */
|
||||
|
||||
o_filehdr.magic = 0x0108; /* see magic.h */
|
||||
o_filehdr.vstamp = 0x0190; /* version stamp */
|
||||
o_filehdr.tsize = stext->data_offset; /* text size in bytes, padded to FW bdry */
|
||||
o_filehdr.dsize = sdata->data_offset; /* initialized data " " */
|
||||
o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */
|
||||
o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */
|
||||
o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */
|
||||
o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */
|
||||
|
||||
|
||||
// create all the section headers
|
||||
|
||||
file_pointer = FILHSZ + sizeof(AOUTHDR);
|
||||
|
||||
CoffTextSectionNo = -1;
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
NSectionsToOutput++;
|
||||
|
||||
if (CoffTextSectionNo == -1 && tcc_sect == stext)
|
||||
CoffTextSectionNo = NSectionsToOutput; // rem which coff sect number the .text sect is
|
||||
|
||||
strcpy(coff_sec->s_name, tcc_sect->name); /* section name */
|
||||
|
||||
coff_sec->s_paddr = tcc_sect->sh_addr; /* physical address */
|
||||
coff_sec->s_vaddr = tcc_sect->sh_addr; /* virtual address */
|
||||
coff_sec->s_size = tcc_sect->data_offset; /* section size */
|
||||
coff_sec->s_scnptr = 0; /* file ptr to raw data for section */
|
||||
coff_sec->s_relptr = 0; /* file ptr to relocation */
|
||||
coff_sec->s_lnnoptr = 0; /* file ptr to line numbers */
|
||||
coff_sec->s_nreloc = 0; /* number of relocation entries */
|
||||
coff_sec->s_flags = GetCoffFlags(coff_sec->s_name); /* flags */
|
||||
coff_sec->s_reserved = 0; /* reserved byte */
|
||||
coff_sec->s_page = 0; /* memory page id */
|
||||
|
||||
file_pointer += sizeof(SCNHDR);
|
||||
}
|
||||
}
|
||||
|
||||
file_hdr.f_nscns = NSectionsToOutput; /* number of sections */
|
||||
|
||||
// now loop through and determine file pointer locations
|
||||
// for the raw data
|
||||
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
// put raw data
|
||||
coff_sec->s_scnptr = file_pointer; /* file ptr to raw data for section */
|
||||
file_pointer += coff_sec->s_size;
|
||||
}
|
||||
}
|
||||
|
||||
// now loop through and determine file pointer locations
|
||||
// for the relocation data
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
// put relocations data
|
||||
if (coff_sec->s_nreloc > 0) {
|
||||
coff_sec->s_relptr = file_pointer; /* file ptr to relocation */
|
||||
file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now loop through and determine file pointer locations
|
||||
// for the line number data
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
coff_sec->s_nlnno = 0;
|
||||
coff_sec->s_lnnoptr = 0;
|
||||
|
||||
if (do_debug && tcc_sect == stext) {
|
||||
// count how many line nos data
|
||||
|
||||
// also find association between source file name and function
|
||||
// so we can sort the symbol table
|
||||
|
||||
|
||||
Stab_Sym *sym, *sym_end;
|
||||
char func_name[MAX_FUNC_NAME_LENGTH],
|
||||
last_func_name[MAX_FUNC_NAME_LENGTH];
|
||||
unsigned long func_addr, last_pc, pc;
|
||||
const char *incl_files[INCLUDE_STACK_SIZE];
|
||||
int incl_index, len, last_line_num;
|
||||
const char *str, *p;
|
||||
|
||||
coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */
|
||||
|
||||
|
||||
func_name[0] = '\0';
|
||||
func_addr = 0;
|
||||
incl_index = 0;
|
||||
last_func_name[0] = '\0';
|
||||
last_pc = 0xffffffff;
|
||||
last_line_num = 1;
|
||||
sym = (Stab_Sym *) stab_section->data + 1;
|
||||
sym_end =
|
||||
(Stab_Sym *) (stab_section->data +
|
||||
stab_section->data_offset);
|
||||
|
||||
nFuncs = 0;
|
||||
while (sym < sym_end) {
|
||||
switch (sym->n_type) {
|
||||
/* function start or end */
|
||||
case N_FUN:
|
||||
if (sym->n_strx == 0) {
|
||||
// end of function
|
||||
|
||||
coff_sec->s_nlnno++;
|
||||
file_pointer += LINESZ;
|
||||
|
||||
pc = sym->n_value + func_addr;
|
||||
func_name[0] = '\0';
|
||||
func_addr = 0;
|
||||
EndAddress[nFuncs] = pc;
|
||||
FuncEntries[nFuncs] =
|
||||
(file_pointer -
|
||||
LineNoFilePtr[nFuncs]) / LINESZ - 1;
|
||||
LastLineNo[nFuncs++] = last_line_num + 1;
|
||||
} else {
|
||||
// beginning of function
|
||||
|
||||
LineNoFilePtr[nFuncs] = file_pointer;
|
||||
coff_sec->s_nlnno++;
|
||||
file_pointer += LINESZ;
|
||||
|
||||
str =
|
||||
(const char *) stabstr_section->data +
|
||||
sym->n_strx;
|
||||
|
||||
p = strchr(str, ':');
|
||||
if (!p) {
|
||||
pstrcpy(func_name, sizeof(func_name), str);
|
||||
pstrcpy(Func[nFuncs], sizeof(func_name), str);
|
||||
} else {
|
||||
len = p - str;
|
||||
if (len > sizeof(func_name) - 1)
|
||||
len = sizeof(func_name) - 1;
|
||||
memcpy(func_name, str, len);
|
||||
memcpy(Func[nFuncs], str, len);
|
||||
func_name[len] = '\0';
|
||||
}
|
||||
|
||||
// save the file that it came in so we can sort later
|
||||
pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
|
||||
incl_files[incl_index - 1]);
|
||||
|
||||
func_addr = sym->n_value;
|
||||
}
|
||||
break;
|
||||
|
||||
/* line number info */
|
||||
case N_SLINE:
|
||||
pc = sym->n_value + func_addr;
|
||||
|
||||
last_pc = pc;
|
||||
last_line_num = sym->n_desc;
|
||||
|
||||
/* XXX: slow! */
|
||||
strcpy(last_func_name, func_name);
|
||||
|
||||
coff_sec->s_nlnno++;
|
||||
file_pointer += LINESZ;
|
||||
break;
|
||||
/* include files */
|
||||
case N_BINCL:
|
||||
str =
|
||||
(const char *) stabstr_section->data + sym->n_strx;
|
||||
add_incl:
|
||||
if (incl_index < INCLUDE_STACK_SIZE) {
|
||||
incl_files[incl_index++] = str;
|
||||
}
|
||||
break;
|
||||
case N_EINCL:
|
||||
if (incl_index > 1)
|
||||
incl_index--;
|
||||
break;
|
||||
case N_SO:
|
||||
if (sym->n_strx == 0) {
|
||||
incl_index = 0; /* end of translation unit */
|
||||
} else {
|
||||
str =
|
||||
(const char *) stabstr_section->data +
|
||||
sym->n_strx;
|
||||
/* do not add path */
|
||||
len = strlen(str);
|
||||
if (len > 0 && str[len - 1] != '/')
|
||||
goto add_incl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
sym++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
file_hdr.f_symptr = file_pointer; /* file pointer to symtab */
|
||||
|
||||
if (do_debug)
|
||||
file_hdr.f_nsyms = coff_nb_syms; /* number of symtab entries */
|
||||
else
|
||||
file_hdr.f_nsyms = 0;
|
||||
|
||||
file_pointer += file_hdr.f_nsyms * SYMNMLEN;
|
||||
|
||||
// OK now we are all set to write the file
|
||||
|
||||
|
||||
fwrite(&file_hdr, FILHSZ, 1, f);
|
||||
fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
|
||||
|
||||
// write section headers
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
fwrite(coff_sec, sizeof(SCNHDR), 1, f);
|
||||
}
|
||||
}
|
||||
|
||||
// write raw data
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
|
||||
}
|
||||
}
|
||||
|
||||
// write relocation data
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
// put relocations data
|
||||
if (coff_sec->s_nreloc > 0) {
|
||||
fwrite(tcc_sect->reloc,
|
||||
coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// group the symbols in order of filename, func1, func2, etc
|
||||
// finally global symbols
|
||||
|
||||
if (do_debug)
|
||||
SortSymbolTable();
|
||||
|
||||
// write line no data
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (do_debug && tcc_sect == stext) {
|
||||
// count how many line nos data
|
||||
|
||||
|
||||
Stab_Sym *sym, *sym_end;
|
||||
char func_name[128], last_func_name[128];
|
||||
unsigned long func_addr, last_pc, pc;
|
||||
const char *incl_files[INCLUDE_STACK_SIZE];
|
||||
int incl_index, len, last_line_num;
|
||||
const char *str, *p;
|
||||
|
||||
LINENO CoffLineNo;
|
||||
|
||||
func_name[0] = '\0';
|
||||
func_addr = 0;
|
||||
incl_index = 0;
|
||||
last_func_name[0] = '\0';
|
||||
last_pc = 0;
|
||||
last_line_num = 1;
|
||||
sym = (Stab_Sym *) stab_section->data + 1;
|
||||
sym_end =
|
||||
(Stab_Sym *) (stab_section->data +
|
||||
stab_section->data_offset);
|
||||
|
||||
while (sym < sym_end) {
|
||||
switch (sym->n_type) {
|
||||
/* function start or end */
|
||||
case N_FUN:
|
||||
if (sym->n_strx == 0) {
|
||||
// end of function
|
||||
|
||||
CoffLineNo.l_addr.l_paddr = last_pc;
|
||||
CoffLineNo.l_lnno = last_line_num + 1;
|
||||
fwrite(&CoffLineNo, 6, 1, f);
|
||||
|
||||
pc = sym->n_value + func_addr;
|
||||
func_name[0] = '\0';
|
||||
func_addr = 0;
|
||||
} else {
|
||||
// beginning of function
|
||||
|
||||
str =
|
||||
(const char *) stabstr_section->data +
|
||||
sym->n_strx;
|
||||
|
||||
|
||||
p = strchr(str, ':');
|
||||
if (!p) {
|
||||
pstrcpy(func_name, sizeof(func_name), str);
|
||||
} else {
|
||||
len = p - str;
|
||||
if (len > sizeof(func_name) - 1)
|
||||
len = sizeof(func_name) - 1;
|
||||
memcpy(func_name, str, len);
|
||||
func_name[len] = '\0';
|
||||
}
|
||||
func_addr = sym->n_value;
|
||||
last_pc = func_addr;
|
||||
last_line_num = -1;
|
||||
|
||||
// output a function begin
|
||||
|
||||
CoffLineNo.l_addr.l_symndx =
|
||||
FindCoffSymbolIndex(func_name);
|
||||
CoffLineNo.l_lnno = 0;
|
||||
|
||||
fwrite(&CoffLineNo, 6, 1, f);
|
||||
}
|
||||
break;
|
||||
|
||||
/* line number info */
|
||||
case N_SLINE:
|
||||
pc = sym->n_value + func_addr;
|
||||
|
||||
|
||||
/* XXX: slow! */
|
||||
strcpy(last_func_name, func_name);
|
||||
|
||||
// output a line reference
|
||||
|
||||
CoffLineNo.l_addr.l_paddr = last_pc;
|
||||
|
||||
if (last_line_num == -1) {
|
||||
CoffLineNo.l_lnno = sym->n_desc;
|
||||
} else {
|
||||
CoffLineNo.l_lnno = last_line_num + 1;
|
||||
}
|
||||
|
||||
fwrite(&CoffLineNo, 6, 1, f);
|
||||
|
||||
last_pc = pc;
|
||||
last_line_num = sym->n_desc;
|
||||
|
||||
break;
|
||||
|
||||
/* include files */
|
||||
case N_BINCL:
|
||||
str =
|
||||
(const char *) stabstr_section->data + sym->n_strx;
|
||||
add_incl2:
|
||||
if (incl_index < INCLUDE_STACK_SIZE) {
|
||||
incl_files[incl_index++] = str;
|
||||
}
|
||||
break;
|
||||
case N_EINCL:
|
||||
if (incl_index > 1)
|
||||
incl_index--;
|
||||
break;
|
||||
case N_SO:
|
||||
if (sym->n_strx == 0) {
|
||||
incl_index = 0; /* end of translation unit */
|
||||
} else {
|
||||
str =
|
||||
(const char *) stabstr_section->data +
|
||||
sym->n_strx;
|
||||
/* do not add path */
|
||||
len = strlen(str);
|
||||
if (len > 0 && str[len - 1] != '/')
|
||||
goto add_incl2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
sym++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write symbol table
|
||||
if (do_debug) {
|
||||
int k;
|
||||
struct syment csym;
|
||||
AUXFUNC auxfunc;
|
||||
AUXBF auxbf;
|
||||
AUXEF auxef;
|
||||
int i;
|
||||
Elf32_Sym *p;
|
||||
const char *name;
|
||||
int nstr;
|
||||
int n = 0;
|
||||
|
||||
Coff_str_table = (char *) tcc_malloc(MAX_STR_TABLE);
|
||||
pCoff_str_table = Coff_str_table;
|
||||
nstr = 0;
|
||||
|
||||
p = (Elf32_Sym *) symtab_section->data;
|
||||
|
||||
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
|
||||
name = symtab_section->link->data + p->st_name;
|
||||
|
||||
for (k = 0; k < 8; k++)
|
||||
csym._n._n_name[k] = 0;
|
||||
|
||||
if (strlen(name) <= 8) {
|
||||
strcpy(csym._n._n_name, name);
|
||||
} else {
|
||||
if (pCoff_str_table - Coff_str_table + strlen(name) >
|
||||
MAX_STR_TABLE - 1)
|
||||
error("String table too large");
|
||||
|
||||
csym._n._n_n._n_zeroes = 0;
|
||||
csym._n._n_n._n_offset =
|
||||
pCoff_str_table - Coff_str_table + 4;
|
||||
|
||||
strcpy(pCoff_str_table, name);
|
||||
pCoff_str_table += strlen(name) + 1; // skip over null
|
||||
nstr++;
|
||||
}
|
||||
|
||||
if (p->st_info == 4) {
|
||||
// put a filename symbol
|
||||
csym.n_value = 33; // ?????
|
||||
csym.n_scnum = N_DEBUG;
|
||||
csym.n_type = 0;
|
||||
csym.n_sclass = C_FILE;
|
||||
csym.n_numaux = 0;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
n++;
|
||||
|
||||
} else if (p->st_info == 0x12) {
|
||||
// find the function data
|
||||
|
||||
for (k = 0; k < nFuncs; k++) {
|
||||
if (strcmp(name, Func[k]) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (k >= nFuncs) {
|
||||
char s[256];
|
||||
|
||||
sprintf(s, "debug info can't find function: %s", name);
|
||||
|
||||
error(s);
|
||||
}
|
||||
// put a Function Name
|
||||
|
||||
csym.n_value = p->st_value; // physical address
|
||||
csym.n_scnum = CoffTextSectionNo;
|
||||
csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
|
||||
csym.n_sclass = C_EXT;
|
||||
csym.n_numaux = 1;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
|
||||
// now put aux info
|
||||
|
||||
auxfunc.tag = 0;
|
||||
auxfunc.size = EndAddress[k] - p->st_value;
|
||||
auxfunc.fileptr = LineNoFilePtr[k];
|
||||
auxfunc.nextsym = n + 6; // tktk
|
||||
auxfunc.dummy = 0;
|
||||
fwrite(&auxfunc, 18, 1, f);
|
||||
|
||||
// put a .bf
|
||||
|
||||
strcpy(csym._n._n_name, ".bf");
|
||||
csym.n_value = p->st_value; // physical address
|
||||
csym.n_scnum = CoffTextSectionNo;
|
||||
csym.n_type = 0;
|
||||
csym.n_sclass = C_FCN;
|
||||
csym.n_numaux = 1;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
|
||||
// now put aux info
|
||||
|
||||
auxbf.regmask = 0;
|
||||
auxbf.lineno = 0;
|
||||
auxbf.nentries = FuncEntries[k];
|
||||
auxbf.localframe = 0;
|
||||
auxbf.nextentry = n + 6;
|
||||
auxbf.dummy = 0;
|
||||
fwrite(&auxbf, 18, 1, f);
|
||||
|
||||
// put a .ef
|
||||
|
||||
strcpy(csym._n._n_name, ".ef");
|
||||
csym.n_value = EndAddress[k]; // physical address
|
||||
csym.n_scnum = CoffTextSectionNo;
|
||||
csym.n_type = 0;
|
||||
csym.n_sclass = C_FCN;
|
||||
csym.n_numaux = 1;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
|
||||
// now put aux info
|
||||
|
||||
auxef.dummy = 0;
|
||||
auxef.lineno = LastLineNo[k];
|
||||
auxef.dummy1 = 0;
|
||||
auxef.dummy2 = 0;
|
||||
auxef.dummy3 = 0;
|
||||
auxef.dummy4 = 0;
|
||||
fwrite(&auxef, 18, 1, f);
|
||||
|
||||
n += 6;
|
||||
|
||||
} else {
|
||||
// try an put some type info
|
||||
|
||||
if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
|
||||
csym.n_type = T_DOUBLE; // int
|
||||
csym.n_sclass = C_EXT;
|
||||
} else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
|
||||
csym.n_type = T_FLOAT;
|
||||
csym.n_sclass = C_EXT;
|
||||
} else if ((p->st_other & VT_BTYPE) == VT_INT) {
|
||||
csym.n_type = T_INT; // int
|
||||
csym.n_sclass = C_EXT;
|
||||
} else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
|
||||
csym.n_type = T_SHORT;
|
||||
csym.n_sclass = C_EXT;
|
||||
} else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
|
||||
csym.n_type = T_CHAR;
|
||||
csym.n_sclass = C_EXT;
|
||||
} else {
|
||||
csym.n_type = T_INT; // just mark as a label
|
||||
csym.n_sclass = C_LABEL;
|
||||
}
|
||||
|
||||
|
||||
csym.n_value = p->st_value;
|
||||
csym.n_scnum = 2;
|
||||
csym.n_numaux = 1;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
|
||||
auxfunc.tag = 0;
|
||||
auxfunc.size = 0x20;
|
||||
auxfunc.fileptr = 0;
|
||||
auxfunc.nextsym = 0;
|
||||
auxfunc.dummy = 0;
|
||||
fwrite(&auxfunc, 18, 1, f);
|
||||
n++;
|
||||
n++;
|
||||
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_debug) {
|
||||
// write string table
|
||||
|
||||
// first write the size
|
||||
i = pCoff_str_table - Coff_str_table;
|
||||
fwrite(&i, 4, 1, f);
|
||||
|
||||
// then write the strings
|
||||
fwrite(Coff_str_table, i, 1, f);
|
||||
|
||||
tcc_free(Coff_str_table);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// group the symbols in order of filename, func1, func2, etc
|
||||
// finally global symbols
|
||||
|
||||
void SortSymbolTable(void)
|
||||
{
|
||||
int i, j, k, n = 0;
|
||||
Elf32_Sym *p, *p2, *NewTable;
|
||||
char *name, *name2;
|
||||
|
||||
NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym));
|
||||
|
||||
p = (Elf32_Sym *) symtab_section->data;
|
||||
|
||||
|
||||
// find a file symbol, copy it over
|
||||
// then scan the whole symbol list and copy any function
|
||||
// symbols that match the file association
|
||||
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
if (p->st_info == 4) {
|
||||
name = (char *) symtab_section->link->data + p->st_name;
|
||||
|
||||
// this is a file symbol, copy it over
|
||||
|
||||
NewTable[n++] = *p;
|
||||
|
||||
p2 = (Elf32_Sym *) symtab_section->data;
|
||||
|
||||
for (j = 0; j < nb_syms; j++) {
|
||||
if (p2->st_info == 0x12) {
|
||||
// this is a func symbol
|
||||
|
||||
name2 =
|
||||
(char *) symtab_section->link->data + p2->st_name;
|
||||
|
||||
// find the function data index
|
||||
|
||||
for (k = 0; k < nFuncs; k++) {
|
||||
if (strcmp(name2, Func[k]) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (k >= nFuncs) {
|
||||
char s[256];
|
||||
|
||||
sprintf(s,
|
||||
"debug (sort) info can't find function: %s",
|
||||
name2);
|
||||
|
||||
error(s);
|
||||
}
|
||||
|
||||
if (strcmp(AssociatedFile[k], name) == 0) {
|
||||
// yes they match copy it over
|
||||
|
||||
NewTable[n++] = *p2;
|
||||
}
|
||||
}
|
||||
p2++;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
// now all the filename and func symbols should have been copied over
|
||||
// copy all the rest over (all except file and funcs)
|
||||
|
||||
p = (Elf32_Sym *) symtab_section->data;
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
if (p->st_info != 4 && p->st_info != 0x12) {
|
||||
NewTable[n++] = *p;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
if (n != nb_syms)
|
||||
error("Internal Compiler error, debug info");
|
||||
|
||||
// copy it all back
|
||||
|
||||
p = (Elf32_Sym *) symtab_section->data;
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
*p++ = NewTable[i];
|
||||
}
|
||||
|
||||
tcc_free(NewTable);
|
||||
}
|
||||
|
||||
|
||||
int FindCoffSymbolIndex(const char *func_name)
|
||||
{
|
||||
int i, n = 0;
|
||||
Elf32_Sym *p;
|
||||
char *name;
|
||||
|
||||
p = (Elf32_Sym *) symtab_section->data;
|
||||
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
|
||||
name = (char *) symtab_section->link->data + p->st_name;
|
||||
|
||||
if (p->st_info == 4) {
|
||||
// put a filename symbol
|
||||
n++;
|
||||
} else if (p->st_info == 0x12) {
|
||||
|
||||
if (strcmp(func_name, name) == 0)
|
||||
return n;
|
||||
|
||||
n += 6;
|
||||
|
||||
// put a Function Name
|
||||
|
||||
// now put aux info
|
||||
|
||||
// put a .bf
|
||||
|
||||
// now put aux info
|
||||
|
||||
// put a .ef
|
||||
|
||||
// now put aux info
|
||||
|
||||
} else {
|
||||
n += 2;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return n; // total number of symbols
|
||||
}
|
||||
|
||||
BOOL OutputTheSection(Section * sect)
|
||||
{
|
||||
const char *s = sect->name;
|
||||
|
||||
if (!strcmp(s, ".text"))
|
||||
return true;
|
||||
else if (!strcmp(s, ".data"))
|
||||
return true;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
short int GetCoffFlags(const char *s)
|
||||
{
|
||||
if (!strcmp(s, ".text"))
|
||||
return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
|
||||
else if (!strcmp(s, ".data"))
|
||||
return STYP_DATA;
|
||||
else if (!strcmp(s, ".bss"))
|
||||
return STYP_BSS;
|
||||
else if (!strcmp(s, ".stack"))
|
||||
return STYP_BSS | STYP_ALIGN | 0x200;
|
||||
else if (!strcmp(s, ".cinit"))
|
||||
return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
Section *FindSection(TCCState * s1, const char *sname)
|
||||
{
|
||||
Section *s;
|
||||
int i;
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
s = s1->sections[i];
|
||||
|
||||
if (!strcmp(sname, s->name))
|
||||
return s;
|
||||
}
|
||||
|
||||
error("could not find section %s", sname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tcc_load_coff(TCCState * s1, int fd)
|
||||
{
|
||||
// tktk TokenSym *ts;
|
||||
|
||||
FILE *f;
|
||||
unsigned int str_size;
|
||||
char *Coff_str_table, *name;
|
||||
int i, k;
|
||||
struct syment csym;
|
||||
char name2[9];
|
||||
FILHDR file_hdr; /* FILE HEADER STRUCTURE */
|
||||
|
||||
f = fdopen(fd, "rb");
|
||||
if (!f) {
|
||||
error("Unable to open .out file for input");
|
||||
}
|
||||
|
||||
if (fread(&file_hdr, FILHSZ, 1, f) != 1)
|
||||
error("error reading .out file for input");
|
||||
|
||||
if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
|
||||
error("error reading .out file for input");
|
||||
|
||||
// first read the string table
|
||||
|
||||
if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
|
||||
error("error reading .out file for input");
|
||||
|
||||
if (fread(&str_size, sizeof(int), 1, f) != 1)
|
||||
error("error reading .out file for input");
|
||||
|
||||
|
||||
Coff_str_table = (char *) tcc_malloc(str_size);
|
||||
|
||||
if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
|
||||
error("error reading .out file for input");
|
||||
|
||||
// read/process all the symbols
|
||||
|
||||
// seek back to symbols
|
||||
|
||||
if (fseek(f, file_hdr.f_symptr, SEEK_SET))
|
||||
error("error reading .out file for input");
|
||||
|
||||
for (i = 0; i < file_hdr.f_nsyms; i++) {
|
||||
if (fread(&csym, SYMESZ, 1, f) != 1)
|
||||
error("error reading .out file for input");
|
||||
|
||||
if (csym._n._n_n._n_zeroes == 0) {
|
||||
name = Coff_str_table + csym._n._n_n._n_offset - 4;
|
||||
} else {
|
||||
name = csym._n._n_name;
|
||||
|
||||
if (name[7] != 0) {
|
||||
for (k = 0; k < 8; k++)
|
||||
name2[k] = name[k];
|
||||
|
||||
name2[8] = 0;
|
||||
|
||||
name = name2;
|
||||
}
|
||||
}
|
||||
// if (strcmp("_DAC_Buffer",name)==0) // tktk
|
||||
// name[0]=0;
|
||||
|
||||
if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) || // structures
|
||||
(csym.n_type == 0x18 && csym.n_sclass == 0x2) || // pointer to structure
|
||||
(csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles
|
||||
(csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats
|
||||
{
|
||||
// strip off any leading underscore (except for other main routine)
|
||||
|
||||
if (name[0] == '_' && strcmp(name, "_main") != 0)
|
||||
name++;
|
||||
|
||||
tcc_add_symbol(s1, name, csym.n_value);
|
||||
}
|
||||
// skip any aux records
|
||||
|
||||
if (csym.n_numaux == 1) {
|
||||
if (fread(&csym, SYMESZ, 1, f) != 1)
|
||||
error("error reading .out file for input");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user