for ( ; *str == ' '; str++)
;
op->reg = reg_val( str);
- if ( *(str+2) == ')') /* (4, a0) */
- op->type = IS_IND_REG_DISPL;
+ 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 != ',';)
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)) &&
case IS_IMMEDIATE : return( 0x3c);
default : fprintf( stderr,
- "mode_reg(), verkeerde operand %d\n",
+ "mode_reg(), wrong operand %d\n",
eaddr->type);
abort();
break;
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);
}
+/* 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));
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));
%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));
}