Fixes to local label stuff

This commit is contained in:
ceriel 1991-10-28 17:59:57 +00:00
parent 45afd0804b
commit dd99f952d5
3 changed files with 30 additions and 8 deletions

View file

@ -786,8 +786,9 @@ C_dup
$1 == 8 ==> "move.l (4, sp), -(sp)"; $1 == 8 ==> "move.l (4, sp), -(sp)";
"move.l (4, sp), -(sp)". "move.l (4, sp), -(sp)".
default ==> "move.l #$1/4, d0"; default ==> "move.l #$1/4, d0";
"lea ($1, sp), a0";
"1:"; "1:";
"move.l ($1-4, sp), -(sp)"; "move.l -(a0), -(sp)";
"sub.l #1, d0"; "sub.l #1, d0";
"bne 1b". "bne 1b".

View file

@ -113,8 +113,15 @@ register struct t_operand *op;
for ( ; *str == ' '; str++) for ( ; *str == ' '; str++)
; ;
op->reg = reg_val( str); op->reg = reg_val( str);
if ( *(str+2) == ')') /* (4, a0) */ if ( *(str+2) == ')') { /* (4, a0) */
op->type = IS_IND_REG_DISPL; int i = atoi(op->expr);
if ((*(op->expr) == '-' ||
isdigit(*(op->expr))) &&
i <= 32767 && i >= -32768) {
op->type = IS_IND_REG_DISPL;
}
else op->type = IS_IND_REG_EDISPL;
}
else { /* (0, sp, d0.l*1) */ else { /* (0, sp, d0.l*1) */
op->type = IS_3_OPS; op->type = IS_3_OPS;
for ( str++; *++str != ',';) for ( str++; *++str != ',';)
@ -218,6 +225,8 @@ register struct t_operand *eaddr;
case IS_IND_REG_DISPL : return( 0x28 | eaddr->reg); case IS_IND_REG_DISPL : return( 0x28 | eaddr->reg);
case IS_IND_REG_EDISPL: return( 0x30 | eaddr->reg);
case IS_GLOB_LBL : return( 0x39); case IS_GLOB_LBL : return( 0x39);
case IS_3_OPS : if ( isdigit( *(eaddr->expr)) && case IS_3_OPS : if ( isdigit( *(eaddr->expr)) &&
@ -231,7 +240,7 @@ register struct t_operand *eaddr;
case IS_IMMEDIATE : return( 0x3c); case IS_IMMEDIATE : return( 0x3c);
default : fprintf( stderr, default : fprintf( stderr,
"mode_reg(), verkeerde operand %d\n", "mode_reg(), wrong operand %d\n",
eaddr->type); eaddr->type);
abort(); abort();
break; break;
@ -266,6 +275,10 @@ register struct t_operand *eaddr;
case IS_IND_REG_DISPL : @text2( %$( eaddr->expr)); case IS_IND_REG_DISPL : @text2( %$( eaddr->expr));
break; break;
case IS_IND_REG_EDISPL :@text2(0x0170);
@text4( %$( eaddr->expr));
break;
case IS_GLOB_LBL : @reloc4( %$(eaddr->lbl), case IS_GLOB_LBL : @reloc4( %$(eaddr->lbl),
%$(eaddr->expr), %$(eaddr->expr),
ABSOLUTE); ABSOLUTE);
@ -313,11 +326,18 @@ struct t_operand *eaddr;
} }
/* The attempts to optimize the instruction size when it cannot be done
at code-expander generation time is actually quite dangerous, because
it may not happen between references to and definitions of (corresponding)
local labels. The reason for this is that these offsets are computed
at code-expander generation time. Unfortunately, no warning is given,
so this has to be checked by hand.
*/
code_instr( opcode, field1, field2, eaddr) code_instr( opcode, field1, field2, eaddr)
int opcode, field1, field2; int opcode, field1, field2;
struct t_operand *eaddr; struct t_operand *eaddr;
{ {
if (eaddr->type == IS_IND_REG_DISPL) { if (eaddr->type == IS_IND_REG_EDISPL) {
@__instr_code(%d(((opcode & 0xf) << 12) | ((field1 & 0x7) << 9) | @__instr_code(%d(((opcode & 0xf) << 12) | ((field1 & 0x7) << 9) |
((field2 & 0x7) << 6)), ((field2 & 0x7) << 6)),
%d(eaddr->reg), %$(eaddr->expr)); %d(eaddr->reg), %$(eaddr->expr));
@ -333,8 +353,8 @@ code_move( size, src, dst)
int size; int size;
struct t_operand *src, *dst; struct t_operand *src, *dst;
{ {
if (src->type == IS_IND_REG_DISPL) { if (src->type == IS_IND_REG_EDISPL) {
if (dst->type == IS_IND_REG_DISPL) { if (dst->type == IS_IND_REG_EDISPL) {
@__moveXX(%d( ((size & 0x3) << 12)), @__moveXX(%d( ((size & 0x3) << 12)),
%d(dst->reg), %$(dst->expr), %d(dst->reg), %$(dst->expr),
%d(src->reg), %$(src->expr)); %d(src->reg), %$(src->expr));
@ -344,7 +364,7 @@ struct t_operand *src, *dst;
%d(src->reg), %$(src->expr)); %d(src->reg), %$(src->expr));
} }
} }
else if (dst->type == IS_IND_REG_DISPL) { else if (dst->type == IS_IND_REG_EDISPL) {
@__move_X(%d( ((size & 0x3) << 12) | (mode_reg( src) & 0x3f)), @__move_X(%d( ((size & 0x3) << 12) | (mode_reg( src) & 0x3f)),
%d(dst->reg), %$(dst->expr)); %d(dst->reg), %$(dst->expr));
} }

View file

@ -21,6 +21,7 @@ struct t_operand {
#define IS_LOC_LBL 12 #define IS_LOC_LBL 12
#define IS_IND_REG 13 #define IS_IND_REG 13
#define IS_IND_REG_DISPL 14 #define IS_IND_REG_DISPL 14
#define IS_IND_REG_EDISPL 15
#define QUICK( op) (op->type == IS_QUICK) #define QUICK( op) (op->type == IS_QUICK)
#define IMMEDIATE( op) (op->type == IS_IMMEDIATE) #define IMMEDIATE( op) (op->type == IS_IMMEDIATE)