#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 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 #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)); }