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)";
|
||||
"move.l (4, sp), -(sp)".
|
||||
default ==> "move.l #$1/4, d0";
|
||||
"lea ($1, sp), a0";
|
||||
"1:";
|
||||
"move.l ($1-4, sp), -(sp)";
|
||||
"move.l -(a0), -(sp)";
|
||||
"sub.l #1, d0";
|
||||
"bne 1b".
|
||||
|
||||
|
|
|
@ -113,8 +113,15 @@ register struct t_operand *op;
|
|||
for ( ; *str == ' '; str++)
|
||||
;
|
||||
op->reg = reg_val( str);
|
||||
if ( *(str+2) == ')') /* (4, a0) */
|
||||
if ( *(str+2) == ')') { /* (4, a0) */
|
||||
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) */
|
||||
op->type = IS_3_OPS;
|
||||
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_EDISPL: return( 0x30 | eaddr->reg);
|
||||
|
||||
case IS_GLOB_LBL : return( 0x39);
|
||||
|
||||
case IS_3_OPS : if ( isdigit( *(eaddr->expr)) &&
|
||||
|
@ -231,7 +240,7 @@ register struct t_operand *eaddr;
|
|||
case IS_IMMEDIATE : return( 0x3c);
|
||||
|
||||
default : fprintf( stderr,
|
||||
"mode_reg(), verkeerde operand %d\n",
|
||||
"mode_reg(), wrong operand %d\n",
|
||||
eaddr->type);
|
||||
abort();
|
||||
break;
|
||||
|
@ -266,6 +275,10 @@ register struct t_operand *eaddr;
|
|||
case IS_IND_REG_DISPL : @text2( %$( eaddr->expr));
|
||||
break;
|
||||
|
||||
case IS_IND_REG_EDISPL :@text2(0x0170);
|
||||
@text4( %$( eaddr->expr));
|
||||
break;
|
||||
|
||||
case IS_GLOB_LBL : @reloc4( %$(eaddr->lbl),
|
||||
%$(eaddr->expr),
|
||||
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)
|
||||
int opcode, field1, field2;
|
||||
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) |
|
||||
((field2 & 0x7) << 6)),
|
||||
%d(eaddr->reg), %$(eaddr->expr));
|
||||
|
@ -333,8 +353,8 @@ code_move( size, src, dst)
|
|||
int size;
|
||||
struct t_operand *src, *dst;
|
||||
{
|
||||
if (src->type == IS_IND_REG_DISPL) {
|
||||
if (dst->type == IS_IND_REG_DISPL) {
|
||||
if (src->type == IS_IND_REG_EDISPL) {
|
||||
if (dst->type == IS_IND_REG_EDISPL) {
|
||||
@__moveXX(%d( ((size & 0x3) << 12)),
|
||||
%d(dst->reg), %$(dst->expr),
|
||||
%d(src->reg), %$(src->expr));
|
||||
|
@ -344,7 +364,7 @@ struct t_operand *src, *dst;
|
|||
%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)),
|
||||
%d(dst->reg), %$(dst->expr));
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ struct t_operand {
|
|||
#define IS_LOC_LBL 12
|
||||
#define IS_IND_REG 13
|
||||
#define IS_IND_REG_DISPL 14
|
||||
#define IS_IND_REG_EDISPL 15
|
||||
|
||||
#define QUICK( op) (op->type == IS_QUICK)
|
||||
#define IMMEDIATE( op) (op->type == IS_IMMEDIATE)
|
||||
|
|
Loading…
Reference in a new issue