Fixes to local label stuff
This commit is contained in:
parent
45afd0804b
commit
dd99f952d5
|
@ -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".
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue