Initial revision
This commit is contained in:
parent
246554a0b1
commit
11dee74e80
6
mach/i86/ce/.distr
Normal file
6
mach/i86/ce/.distr
Normal file
|
@ -0,0 +1,6 @@
|
|||
EM_table
|
||||
as.c
|
||||
as.h
|
||||
as_table
|
||||
mach.c
|
||||
mach.h
|
1146
mach/i86/ce/EM_table
Normal file
1146
mach/i86/ce/EM_table
Normal file
File diff suppressed because it is too large
Load diff
312
mach/i86/ce/as.c
Normal file
312
mach/i86/ce/as.c
Normal file
|
@ -0,0 +1,312 @@
|
|||
#include "arg_type.h"
|
||||
#include "as.h"
|
||||
|
||||
static struct t_operand dummy = { IS_REG, AX, 0, 0, 0};
|
||||
struct t_operand saved_op, *AX_oper = &dummy;
|
||||
|
||||
save_op( op)
|
||||
struct t_operand *op;
|
||||
{
|
||||
saved_op.type = op->type;
|
||||
saved_op.reg = op->reg;
|
||||
saved_op.expr = op->expr;
|
||||
saved_op.lab = op->lab;
|
||||
saved_op.off = op->off;
|
||||
}
|
||||
|
||||
#define last( s) ( s + strlen( s) - 1)
|
||||
#define LEFT '('
|
||||
#define RIGHT ')'
|
||||
#define DOLLAR '$'
|
||||
|
||||
block_assemble( instr, nr, first, Last)
|
||||
char **instr;
|
||||
int nr, first, Last;
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( first) {
|
||||
if( strncmp( instr[0], "pop", 3) == 0) {
|
||||
*instr[0] = 'P';
|
||||
*( instr[0]+1) = 'O';
|
||||
*( instr[0]+2) = 'P';
|
||||
}
|
||||
else
|
||||
@clean_push_buf();
|
||||
}
|
||||
if ( Last && strncmp( instr[nr-1], "push", 4) == 0) {
|
||||
*instr[nr-1] = 'P';
|
||||
*( instr[nr-1]+1) = 'U';
|
||||
*( instr[nr-1]+2) = 'S';
|
||||
*( instr[nr-1]+3) = 'H';
|
||||
}
|
||||
|
||||
for( i=0; i<nr; i++)
|
||||
assemble( instr[i]);
|
||||
}
|
||||
|
||||
|
||||
process_label( l)
|
||||
char *l;
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
process_mnemonic( m)
|
||||
char *m;
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
process_operand( str, op)
|
||||
char *str;
|
||||
struct t_operand *op;
|
||||
|
||||
/* expr -> IS_DATA en IS_LABEL
|
||||
* reg -> IS_REG en IS_ACCU
|
||||
* (expr) -> IS_ADDR
|
||||
* expr(reg) -> IS_MEM
|
||||
*/
|
||||
{
|
||||
char *ptr, *index();
|
||||
|
||||
op->type = UNKNOWN;
|
||||
if ( *last( str) == RIGHT) {
|
||||
ptr = index( str, LEFT);
|
||||
*last( str) = '\0';
|
||||
*ptr = '\0';
|
||||
if ( is_reg( ptr+1, op)) {
|
||||
op->type = IS_MEM;
|
||||
op->expr = ( *str == '\0' ? "0" : str);
|
||||
}
|
||||
else {
|
||||
set_label( ptr+1, op);
|
||||
op->type = IS_ADDR;
|
||||
}
|
||||
}
|
||||
else
|
||||
if ( is_reg( str, op))
|
||||
op->type = IS_REG;
|
||||
else {
|
||||
if ( contains_label( str))
|
||||
set_label( str, op);
|
||||
else {
|
||||
op->type = IS_DATA;
|
||||
op->expr = str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int is_reg( str, op)
|
||||
char *str;
|
||||
struct t_operand *op;
|
||||
{
|
||||
if ( strlen( str) != 2)
|
||||
return( 0);
|
||||
|
||||
switch ( *(str+1)) {
|
||||
case 'x' :
|
||||
case 'l' : switch( *str) {
|
||||
case 'a' : op->reg = 0;
|
||||
return( TRUE);
|
||||
|
||||
case 'c' : op->reg = 1;
|
||||
return( TRUE);
|
||||
|
||||
case 'd' : op->reg = 2;
|
||||
return( TRUE);
|
||||
|
||||
case 'b' : op->reg = 3;
|
||||
return( TRUE);
|
||||
|
||||
default : return( FALSE);
|
||||
}
|
||||
|
||||
case 'h' : switch( *str) {
|
||||
case 'a' : op->reg = 4;
|
||||
return( TRUE);
|
||||
|
||||
case 'c' : op->reg = 5;
|
||||
return( TRUE);
|
||||
|
||||
case 'd' : op->reg = 6;
|
||||
return( TRUE);
|
||||
|
||||
case 'b' : op->reg = 7;
|
||||
return( TRUE);
|
||||
|
||||
default : return( FALSE);
|
||||
}
|
||||
|
||||
case 'p' : switch ( *str) {
|
||||
case 's' : op->reg = 4;
|
||||
return( TRUE);
|
||||
|
||||
case 'b' : op->reg = 5;
|
||||
return( TRUE);
|
||||
|
||||
default : return( FALSE);
|
||||
}
|
||||
|
||||
case 'i' : switch ( *str) {
|
||||
case 's' : op->reg = 6;
|
||||
return( TRUE);
|
||||
|
||||
case 'd' : op->reg = 7;
|
||||
return( TRUE);
|
||||
|
||||
default : return( FALSE);
|
||||
}
|
||||
|
||||
default : return( FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
#include <ctype.h>
|
||||
#define isletter( c) ( isalpha( c) || c == '_')
|
||||
|
||||
int contains_label( str)
|
||||
char *str;
|
||||
{
|
||||
while( !isletter( *str) && *str != '\0')
|
||||
if ( *str == '$')
|
||||
if ( arg_type( str) == STRING)
|
||||
return( TRUE);
|
||||
else
|
||||
str += 2;
|
||||
else
|
||||
str++;
|
||||
|
||||
return( isletter( *str));
|
||||
}
|
||||
|
||||
set_label( str, op)
|
||||
char *str;
|
||||
struct t_operand *op;
|
||||
{
|
||||
char *ptr, *index(), *sprint();
|
||||
static char buf[256];
|
||||
|
||||
ptr = index( str, '+');
|
||||
|
||||
if ( ptr == 0)
|
||||
op->off = "0";
|
||||
else {
|
||||
*ptr = '\0';
|
||||
op->off = ptr + 1;
|
||||
}
|
||||
|
||||
if ( isdigit( *str) && ( *(str+1) == 'b' || *(str+1) == 'f') &&
|
||||
*(str+2) == '\0') {
|
||||
*(str+1) = '\0'; /* b of f verwijderen! */
|
||||
op->lab = str;
|
||||
op->type = IS_ILB;
|
||||
}
|
||||
else {
|
||||
op->type = IS_LABEL;
|
||||
if ( index( str, DOLLAR) != 0)
|
||||
op->lab = str;
|
||||
else
|
||||
/* nood oplossing */
|
||||
op->lab = sprint( buf, "\"%s\"", str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
|
||||
mod_RM( reg, op)
|
||||
int reg;
|
||||
struct t_operand *op;
|
||||
{
|
||||
if ( REG( op))
|
||||
R233( 0x3, reg, op->reg);
|
||||
else if ( ADDR( op)) {
|
||||
R233( 0x0, reg, 0x6);
|
||||
@reloc2( %$(op->lab), %$(op->off), ABSOLUTE);
|
||||
}
|
||||
else if ( strcmp( op->expr, "0") == 0)
|
||||
switch( op->reg) {
|
||||
case SI : R233( 0x0, reg, 0x4);
|
||||
break;
|
||||
|
||||
case DI : R233( 0x0, reg, 0x5);
|
||||
break;
|
||||
|
||||
case BP : R233( 0x1, reg, 0x6); /* Uitzondering! */
|
||||
@text1( 0);
|
||||
break;
|
||||
|
||||
case BX : R233( 0x0, reg, 0x7);
|
||||
break;
|
||||
|
||||
default : fprint( STDERR, "Wrong index register %d\n",
|
||||
op->reg);
|
||||
}
|
||||
else {
|
||||
@if ( fit_byte( %$(op->expr)))
|
||||
switch( op->reg) {
|
||||
case SI : R233( 0x1, reg, 0x4);
|
||||
break;
|
||||
|
||||
case DI : R233( 0x1, reg, 0x5);
|
||||
break;
|
||||
|
||||
case BP : R233( 0x1, reg, 0x6);
|
||||
break;
|
||||
|
||||
case BX : R233( 0x1, reg, 0x7);
|
||||
break;
|
||||
|
||||
default : fprint( STDERR, "Wrong index register %d\n",
|
||||
op->reg);
|
||||
}
|
||||
@text1( %$(op->expr));
|
||||
@else
|
||||
switch( op->reg) {
|
||||
case SI : R233( 0x2, reg, 0x4);
|
||||
break;
|
||||
|
||||
case DI : R233( 0x2, reg, 0x5);
|
||||
break;
|
||||
|
||||
case BP : R233( 0x2, reg, 0x6);
|
||||
break;
|
||||
|
||||
case BX : R233( 0x2, reg, 0x7);
|
||||
break;
|
||||
|
||||
default : fprint( STDERR, "Wrong index register %d\n",
|
||||
op->reg);
|
||||
}
|
||||
@text2( %$(op->expr));
|
||||
@fi
|
||||
}
|
||||
}
|
||||
|
||||
mov_REG_EADDR( dst, src)
|
||||
struct t_operand *dst, *src;
|
||||
{
|
||||
if ( REG(src) && dst->reg == src->reg)
|
||||
; /* Nothing!! result of push/pop optimization */
|
||||
else {
|
||||
@text1( 0x8b);
|
||||
mod_RM( dst->reg, src);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
R233( a, b, c)
|
||||
int a,b,c;
|
||||
{
|
||||
@text1( %d( (a << 6) | ( b << 3) | c));
|
||||
}
|
||||
|
||||
|
||||
R53( a, b)
|
||||
int a,b;
|
||||
{
|
||||
@text1( %d( (a << 3) | b));
|
||||
}
|
40
mach/i86/ce/as.h
Normal file
40
mach/i86/ce/as.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#define UNKNOWN 0
|
||||
#define IS_REG 0x1
|
||||
#define IS_ACCU 0x2
|
||||
#define IS_DATA 0x4
|
||||
#define IS_LABEL 0x8
|
||||
#define IS_MEM 0x10
|
||||
#define IS_ADDR 0x20
|
||||
#define IS_ILB 0x40
|
||||
|
||||
#define AX 0
|
||||
#define BX 3
|
||||
#define CL 1
|
||||
#define SP 4
|
||||
#define BP 5
|
||||
#define SI 6
|
||||
#define DI 7
|
||||
|
||||
#define REG( op) ( op->type & IS_REG)
|
||||
#define ACCU( op) ( op->type & IS_REG && op->reg == AX)
|
||||
#define REG_CL( op) ( op->type & IS_REG && op->reg == CL)
|
||||
#define DATA( op) ( op->type & IS_DATA)
|
||||
#define lABEL( op) ( op->type & IS_LABEL)
|
||||
#define ILB( op) ( op->type & IS_ILB)
|
||||
#define MEM( op) ( op->type & IS_MEM)
|
||||
#define ADDR( op) ( op->type & IS_ADDR)
|
||||
#define EADDR( op) ( op->type & ( IS_ADDR | IS_MEM | IS_REG))
|
||||
#define CONST1( op) ( op->type & IS_DATA && strcmp( "1", op->expr) == 0)
|
||||
#define MOVS( op) ( op->type & IS_LABEL&&strcmp("\"movs\"", op->lab) == 0)
|
||||
#define IMMEDIATE( op) ( op->type & ( IS_DATA | IS_LABEL))
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
struct t_operand {
|
||||
unsigned type;
|
||||
int reg;
|
||||
char *expr, *lab, *off;
|
||||
};
|
||||
|
||||
extern struct t_operand saved_op, *AX_oper;
|
228
mach/i86/ce/as_table
Normal file
228
mach/i86/ce/as_table
Normal file
|
@ -0,0 +1,228 @@
|
|||
adc dst:REG, src:EADDR ==> @text1( 0x13);
|
||||
mod_RM( dst->reg, src).
|
||||
|
||||
add dst:REG, src:EADDR ==> @text1( 0x3);
|
||||
mod_RM( dst->reg, src).
|
||||
|
||||
... dst:ACCU, src:DATA ==> @text1( 0x5);
|
||||
@text2( %$(src->expr)).
|
||||
|
||||
... dst:EADDR, src:DATA ==> @text1( 0x81);
|
||||
mod_RM( 0, dst);
|
||||
@text2( %$(src->expr)).
|
||||
|
||||
... dst:ACCU, src:lABEL ==> @text1( 0x5);
|
||||
@reloc2( %$(src->lab), %$(src->off), !PC_REL).
|
||||
|
||||
... dst:EADDR, src:lABEL ==> @text1( 0x81);
|
||||
mod_RM( 0, dst);
|
||||
@reloc2( %$(src->lab), %$(src->off), !PC_REL).
|
||||
|
||||
and dst:REG, src:EADDR ==> @text1( 0x23);
|
||||
mod_RM( dst->reg, src).
|
||||
|
||||
... dst:ACCU, src:DATA ==> @text1( 0x25);
|
||||
@text2( %$(src->expr)).
|
||||
|
||||
call dst:lABEL ==> @text1( 0xe8);
|
||||
@reloc2( %$(dst->lab), %$(dst->off), PC_REL).
|
||||
|
||||
... dst:EADDR ==> @text1( 0xff);
|
||||
mod_RM( 2, dst).
|
||||
|
||||
cmp dst:REG, src:EADDR ==> @text1( 0x3b);
|
||||
mod_RM( dst->reg, src).
|
||||
|
||||
... dst:ACCU, src:DATA ==> @text1( 0x3d);
|
||||
@text2( %$(src->expr)).
|
||||
|
||||
cwd ==> @text1( 0x99).
|
||||
|
||||
dec dst:REG ==> R53( 9, dst->reg).
|
||||
|
||||
... dst:EADDR ==> @text1( 0xff);
|
||||
mod_RM( 1, dst).
|
||||
|
||||
div divisor:EADDR ==> @text1( 0xf7);
|
||||
mod_RM( 6, divisor).
|
||||
|
||||
idiv divisor:EADDR ==> @text1( 0xf7);
|
||||
mod_RM( 7, divisor).
|
||||
|
||||
inc dst:REG ==> R53( 8, dst->reg).
|
||||
|
||||
... dst:EADDR ==> @text1( 0xff);
|
||||
mod_RM( 0, dst).
|
||||
|
||||
jb dst:ILB ==> @text1( 0x72);
|
||||
@text1( %dist( dst->lab)).
|
||||
|
||||
je dst:ILB ==> @text1( 0x74);
|
||||
@text1( %dist( dst->lab)).
|
||||
|
||||
... dst:lABEL ==> save_op( dst);
|
||||
assemble( "jne 9f");
|
||||
jmp_instr( &saved_op);
|
||||
assemble( "9:").
|
||||
|
||||
jg dst:ILB ==> @text1( 0x7f);
|
||||
@text1( %dist( dst->lab)).
|
||||
|
||||
... dst:lABEL ==> save_op( dst);
|
||||
assemble( "jle 9f");
|
||||
jmp_instr( &saved_op);
|
||||
assemble( "9:").
|
||||
|
||||
jge dst:ILB ==> @text1( 0x7d);
|
||||
@text1( %dist( dst->lab)).
|
||||
|
||||
... dst:lABEL ==> save_op( dst);
|
||||
assemble( "jl 9f");
|
||||
jmp_instr( &saved_op);
|
||||
assemble( "9:").
|
||||
|
||||
jl dst:ILB ==> @text1( 0x7c);
|
||||
@text1( %dist( dst->lab)).
|
||||
|
||||
... dst:lABEL ==> save_op( dst);
|
||||
assemble( "jge 9f");
|
||||
jmp_instr( &saved_op);
|
||||
assemble( "9:").
|
||||
|
||||
jle dst:ILB ==> @text1( 0x7e);
|
||||
@text1( %dist( dst->lab)).
|
||||
|
||||
... dst:lABEL ==> save_op( dst);
|
||||
assemble( "jg 9f");
|
||||
jmp_instr( &saved_op);
|
||||
assemble( "9:").
|
||||
|
||||
jmp dst:ILB ==> @text1( 0xeb);
|
||||
@text1( %dist( dst->lab)).
|
||||
|
||||
... dst:lABEL ==> @text1( 0xe9);
|
||||
@reloc2( %$(dst->lab), %$(dst->off), PC_REL).
|
||||
|
||||
jne dst:ILB ==> @text1( 0x75);
|
||||
@text1( %dist( dst->lab)).
|
||||
|
||||
... dst:lABEL ==> save_op( dst);
|
||||
assemble( "je 9f");
|
||||
jmp_instr( &saved_op);
|
||||
assemble( "9:").
|
||||
|
||||
lea dst:REG, src:EADDR ==> @text1( 0x8d);
|
||||
mod_RM( dst->reg, src).
|
||||
|
||||
loop dst:ILB ==> @text1( 0xe2);
|
||||
@text1( %dist( dst->lab)).
|
||||
|
||||
mov dst:REG, src:EADDR ==> mov_REG_EADDR( dst, src).
|
||||
|
||||
... dst:REG, src:DATA ==> R53( 0x17, dst->reg);
|
||||
@text2( %$(src->expr)).
|
||||
|
||||
... dst:REG, src:lABEL ==> R53( 0x17, dst->reg);
|
||||
@reloc2( %$(src->lab), %$(src->off), !PC_REL).
|
||||
|
||||
... dst:EADDR, src:REG ==> @text1( 0x89);
|
||||
mod_RM( src->reg, dst).
|
||||
|
||||
... dst:EADDR, src:DATA ==> @text1( 0xc7);
|
||||
mod_RM( 0, dst);
|
||||
@text2( %$(src->expr)).
|
||||
|
||||
... dst:EADDR, src:lABEL ==> @text1( 0xc7);
|
||||
mod_RM( 0, dst);
|
||||
@reloc2( %$(src->lab), %$(src->off), !PC_REL).
|
||||
|
||||
movb dst:REG, src:EADDR ==> @text1( 0x8a);
|
||||
mod_RM( dst->reg, src).
|
||||
|
||||
... dst:EADDR, src:REG ==> @text1( 0x88);
|
||||
mod_RM( src->reg, dst).
|
||||
|
||||
mul mplier:EADDR ==> @text1( 0xf7);
|
||||
mod_RM( 4, mplier).
|
||||
|
||||
neg dst:EADDR ==> @text1( 0xf7);
|
||||
mod_RM( 3, dst).
|
||||
|
||||
not dst:EADDR ==> @text1( 0xf7);
|
||||
mod_RM( 2, dst).
|
||||
|
||||
or dst:REG, src:EADDR ==> @text1( 0x0b);
|
||||
mod_RM( dst->reg, src).
|
||||
|
||||
pop dst:REG ==> R53( 0xb, dst->reg).
|
||||
|
||||
... dst:EADDR ==> @text1( 0x8f);
|
||||
mod_RM( 0, dst).
|
||||
|
||||
POP dst ==> @if ( push_waiting)
|
||||
mov_instr( dst, AX_oper);
|
||||
@assign( push_waiting, FALSE).
|
||||
@else
|
||||
pop_instr( dst).
|
||||
@fi.
|
||||
|
||||
push src:REG ==> R53( 0xa, src->reg).
|
||||
|
||||
... src:EADDR ==> @text1( 0xff);
|
||||
mod_RM( 6, src).
|
||||
|
||||
PUSH src ==> mov_instr( AX_oper, src);
|
||||
@assign( push_waiting, TRUE).
|
||||
|
||||
rcr dst:EADDR, src:CONST1 ==> @text1( 0xd1);
|
||||
mod_RM( 3, dst).
|
||||
|
||||
rep ins:MOVS ==> @text1( 0xf3);
|
||||
@text1( 0xa5). /* Wie zet direction flag? */
|
||||
|
||||
ret ==> @text1( 0xc3). /* Altijd NEAR! */
|
||||
|
||||
rol dst:EADDR, src:REG_CL ==> @text1( 0xd3);
|
||||
mod_RM( 0, dst).
|
||||
|
||||
ror dst:EADDR, src:REG_CL ==> @text1( 0xd3);
|
||||
mod_RM( 1, dst).
|
||||
|
||||
sal dst:EADDR, src:REG_CL ==> @text1( 0xd3);
|
||||
mod_RM( 4, dst).
|
||||
|
||||
sar dst:EADDR, src:REG_CL ==> @text1( 0xd3);
|
||||
mod_RM( 7, dst).
|
||||
|
||||
... dst:EADDR, src:CONST1 ==> @text1( 0xd1);
|
||||
mod_RM( 7, dst).
|
||||
|
||||
sbb dst:REG, src:EADDR ==> @text1( 0x1b);
|
||||
mod_RM( dst->reg, src).
|
||||
|
||||
... dst:ACCU, src:DATA ==> @text1( 0x1d);
|
||||
@text2( %$(src->expr)).
|
||||
|
||||
shl dst, src ==> sal_instr( dst, src).
|
||||
|
||||
shr dst:EADDR, src:REG_CL ==> @text1( 0xd3);
|
||||
mod_RM( 5, dst).
|
||||
|
||||
... dst:EADDR, src:CONST1 ==> @text1( 0xd1);
|
||||
mod_RM( 5, dst).
|
||||
|
||||
sub dst:REG, src:EADDR ==> @text1( 0x2b);
|
||||
mod_RM( dst->reg, src).
|
||||
|
||||
... dst:EADDR, src:DATA ==> @text1( 0x81);
|
||||
mod_RM( 5, dst);
|
||||
@text2( %$(src->expr)).
|
||||
|
||||
test dst:REG, src:EADDR ==> @text1( 0x85);
|
||||
mod_RM( dst->reg, src).
|
||||
|
||||
xchg dst:EADDR, src:REG ==> @text1( 0x87);
|
||||
mod_RM( src->reg, dst).
|
||||
|
||||
xor dst:REG, src:EADDR ==> @text1( 0x33);
|
||||
mod_RM( dst->reg, src).
|
17
mach/i86/ce/mach.c
Normal file
17
mach/i86/ce/mach.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include <system.h>
|
||||
#include "mach.h"
|
||||
|
||||
arg_error( s, arg)
|
||||
char *s;
|
||||
int arg;
|
||||
{
|
||||
fprint( STDERR, "arg_error %s %d\n", s, arg);
|
||||
}
|
||||
|
||||
int push_waiting = FALSE;
|
||||
|
||||
int fit_byte( val)
|
||||
int val;
|
||||
{
|
||||
return( val >= -128 && val <= 127);
|
||||
}
|
26
mach/i86/ce/mach.h
Normal file
26
mach/i86/ce/mach.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#define BSS_INIT 0
|
||||
|
||||
#define ONE_BYTE int
|
||||
#define TWO_BYTES int
|
||||
#define FOUR_BYTES long
|
||||
|
||||
|
||||
#define EM_WSIZE 2
|
||||
#define EM_PSIZE 2
|
||||
#define EM_BSIZE 4
|
||||
|
||||
|
||||
#define NAME_FMT "_%s"
|
||||
#define DNAM_FMT "_%s"
|
||||
#define DLB_FMT "I_%ld"
|
||||
#define ILB_FMT "I%03d%ld"
|
||||
#define HOL_FMT "hol%d"
|
||||
|
||||
#define GENLAB 'I'
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define clean_push_buf() if(push_waiting){text1(0x50);push_waiting=FALSE;}
|
||||
#define assign( l, r) l = r
|
||||
extern int push_waiting;
|
Loading…
Reference in a new issue