Browse Source

assembling of (xxx,a6) addressing mode was wrong for large values of xxx

ceriel 33 years ago
parent
commit
2094dcecfe
2 changed files with 70 additions and 6 deletions
  1. 29 5
      mach/sun3/ce/as.c
  2. 41 1
      mach/sun3/ce/mach.c

+ 29 - 5
mach/sun3/ce/as.c

@@ -317,8 +317,15 @@ code_instr( opcode, field1, field2, eaddr)
 int opcode, field1, field2;
 struct t_operand *eaddr;
 {
-	code_opcode( opcode, field1, field2, eaddr);
-	code_extension( eaddr);
+	if (eaddr->type == IS_IND_REG_DISPL) {
+		@__instr_code(%d(((opcode & 0xf) << 12) | ((field1 & 0x7) << 9) |
+			        ((field2 & 0x7) << 6)),
+			      %d(eaddr->reg), %$(eaddr->expr));
+	}
+	else {
+		code_opcode( opcode, field1, field2, eaddr);
+		code_extension( eaddr);
+	}
 }
 
 
@@ -326,10 +333,27 @@ code_move( size, src, dst)
 int size;
 struct t_operand *src, *dst;
 {
-	@text2( %d( ((size & 0x3) << 12) | ((reg_mode( dst) & 0x3f) << 6) |
+	if (src->type == IS_IND_REG_DISPL) {
+		if (dst->type == IS_IND_REG_DISPL) {
+			@__moveXX(%d( ((size & 0x3) << 12)),
+				 %d(dst->reg), %$(dst->expr),
+				 %d(src->reg), %$(src->expr));
+		}
+		else {
+			@__instr_code(%d( ((size & 0x3) << 12)|((reg_mode( dst) & 0x3f) << 6)),
+				 %d(src->reg), %$(src->expr));
+		}
+	}
+	else if (dst->type == IS_IND_REG_DISPL) {
+		@__move_X(%d( ((size & 0x3) << 12) | (mode_reg( src) & 0x3f)),
+			 %d(dst->reg), %$(dst->expr));
+	}
+	else {
+		@text2( %d( ((size & 0x3) << 12) | ((reg_mode( dst) & 0x3f) << 6) |
 		    	     		   (mode_reg( src) & 0x3f)));
-	code_extension( src);
-	code_extension( dst);
+		code_extension( src);
+		code_extension( dst);
+	}
 }
 
 

+ 41 - 1
mach/sun3/ce/mach.c

@@ -1,7 +1,6 @@
 #define CODE_EXPANDER
 #include "mach.h"
 #include <back.h>
-#include <out.h>
 #include <system.h>
 
 
@@ -28,3 +27,44 @@ char *filename;
 */
 
 #include <con_float>
+
+__instr_code(code, reg, off)
+{
+  if (off <= 32767 & off >= -32768) {
+	text2(code|0x28|reg);
+	text2(off);
+	return;
+  }
+  text2(code|0x30|reg);
+  text2(0x0170);
+  text4(off);
+}
+
+__move_X(code, reg, off)
+{
+  if (off <= 32767 & off >= -32768) {
+	text2(code|(reg<<9)|0x140);
+	text2(off);
+	return;
+  }
+  text2(code|(reg<<9)|0x180);
+  text2(0x0170);
+  text4(off);
+}
+
+__moveXX(code, srcreg, srcoff, dstreg, dstoff)
+{
+  if (srcoff <= 32767 && srcoff >= -32768) {
+	__move_X(code|0x28|srcreg, dstreg, dstoff);
+	return;
+  }
+  if (dstoff <= 32767 && dstoff >= -32768) {
+	__instr_code(code|0x140|(dstreg<<9), srcreg, srcoff);
+	return;
+  }
+  text2(code|(dstreg<<9)|srcreg|0x180|0x30);
+  text2(0x0170);
+  text4(srcoff);
+  text2(0x0170);
+  text4(dstoff);
+}