diff 68kinst.c @ 15:c0f339564819

Make x86 generator generic with respect to operand size for immediate parameters.
author Mike Pavone <pavone@retrodev.com>
date Tue, 27 Nov 2012 22:43:32 -0800
parents 168b1a873895
children 3e7bfde7606e
line wrap: on
line diff
--- a/68kinst.c	Tue Nov 27 09:28:13 2012 -0800
+++ b/68kinst.c	Tue Nov 27 22:43:32 2012 -0800
@@ -39,12 +39,12 @@
 		case 0:
 			dst->addr_mode = MODE_ABSOLUTE_SHORT;
 			ext = *(++cur);
-			dst->params.u32 = sign_extend16(ext);
+			dst->params.immed = sign_extend16(ext);
 			break;
 		case 1:
 			dst->addr_mode = MODE_ABSOLUTE;
 			ext = *(++cur);
-			dst->params.u32 = ext << 16 | *(++cur);
+			dst->params.immed = ext << 16 | *(++cur);
 			break;
 		case 2:
 			dst->addr_mode = MODE_PC_DISPLACE;
@@ -57,13 +57,13 @@
 			switch (size)
 			{
 			case OPSIZE_BYTE:
-				dst->params.u8 = ext;
+				dst->params.immed = ext & 0xFF;
 				break;
 			case OPSIZE_WORD:
-				dst->params.u16 = ext;
+				dst->params.immed = ext;
 				break;
 			case OPSIZE_LONG:
-				dst->params.u32 = ext << 16 | *(++cur);
+				dst->params.immed = ext << 16 | *(++cur);
 				break;
 			}
 			break;
@@ -145,7 +145,7 @@
 			opmode = (*istream >> 3) & 0x7;
 			reg = *istream & 0x7;
 			decoded->src.addr_mode = MODE_IMMEDIATE;
-			decoded->src.params.u8 = *(++istream);
+			decoded->src.params.immed = *(++istream) & 0xFF;
 			decoded->extra.size = OPSIZE_BYTE;
 			istream = m68k_decode_op_ex(istream, opmode, reg, OPSIZE_BYTE, &(decoded->dst));
 		} else if ((*istream & 0xC0) == 0xC0) {
@@ -160,12 +160,12 @@
 					decoded->op = M68K_ORI_CCR;
 					decoded->extra.size = OPSIZE_BYTE;
 					decoded->src.addr_mode = MODE_IMMEDIATE;
-					decoded->src.params.u8 = *(++istream);
+					decoded->src.params.immed = *(++istream) & 0xFF;
 				} else if((*istream & 0xFF) == 0x7C) {
 					decoded->op = M68K_ORI_SR;
 					decoded->extra.size = OPSIZE_WORD;
 					decoded->src.addr_mode = MODE_IMMEDIATE;
-					decoded->src.params.u16 = *(++istream);
+					decoded->src.params.immed = *(++istream);
 				} else {
 					decoded->op = M68K_OR;
 					decoded->variant = VAR_IMMEDIATE;
@@ -176,14 +176,14 @@
 					switch (size)
 					{
 					case OPSIZE_BYTE:
-						decoded->src.params.u8 = *(++istream);
+						decoded->src.params.immed = *(++istream) & 0xFF;
 						break;
 					case OPSIZE_WORD:
-						decoded->src.params.u16 = *(++istream);
+						decoded->src.params.immed = *(++istream);
 						break;
 					case OPSIZE_LONG:
 						immed = *(++istream);
-						decoded->src.params.u32 = immed << 16 | *(++istream);
+						decoded->src.params.immed = immed << 16 | *(++istream);
 						break;
 					}
 					istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
@@ -195,12 +195,12 @@
 					decoded->op = M68K_ANDI_CCR;
 					decoded->extra.size = OPSIZE_BYTE;
 					decoded->src.addr_mode = MODE_IMMEDIATE;
-					decoded->src.params.u8 = *(++istream);
+					decoded->src.params.immed = *(++istream) & 0xFF;
 				} else if((*istream & 0xFF) == 0x7C) {
 					decoded->op = M68K_ANDI_SR;
 					decoded->extra.size = OPSIZE_WORD;
 					decoded->src.addr_mode = MODE_IMMEDIATE;
-					decoded->src.params.u16 = *(++istream);
+					decoded->src.params.immed = *(++istream);
 				} else {
 					decoded->op = M68K_AND;
 					decoded->variant = VAR_IMMEDIATE;
@@ -211,14 +211,14 @@
 					switch (size)
 					{
 					case OPSIZE_BYTE:
-						decoded->src.params.u8 = *(++istream);
+						decoded->src.params.immed = *(++istream) & 0xFF;
 						break;
 					case OPSIZE_WORD:
-						decoded->src.params.u16 = *(++istream);
+						decoded->src.params.immed = *(++istream);
 						break;
 					case OPSIZE_LONG:
 						immed = *(++istream);
-						decoded->src.params.u32 = immed << 16 | *(++istream);
+						decoded->src.params.immed = immed << 16 | *(++istream);
 						break;
 					}
 					istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
@@ -234,14 +234,14 @@
 				switch (size)
 				{
 				case OPSIZE_BYTE:
-					decoded->src.params.u8 = *(++istream);
+					decoded->src.params.immed = *(++istream) & 0xFF;
 					break;
 				case OPSIZE_WORD:
-					decoded->src.params.u16 = *(++istream);
+					decoded->src.params.immed = *(++istream);
 					break;
 				case OPSIZE_LONG:
 					immed = *(++istream);
-					decoded->src.params.u32 = immed << 16 | *(++istream);
+					decoded->src.params.immed = immed << 16 | *(++istream);
 					break;
 				}
 				istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
@@ -256,14 +256,14 @@
 				switch (size)
 				{
 				case OPSIZE_BYTE:
-					decoded->src.params.u8 = *(++istream);
+					decoded->src.params.immed = *(++istream) & 0xFF;
 					break;
 				case OPSIZE_WORD:
-					decoded->src.params.u16 = *(++istream);
+					decoded->src.params.immed = *(++istream);
 					break;
 				case OPSIZE_LONG:
 					immed = *(++istream);
-					decoded->src.params.u32 = immed << 16 | *(++istream);
+					decoded->src.params.immed = immed << 16 | *(++istream);
 					break;
 				}
 				istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
@@ -286,7 +286,7 @@
 					break;
 				}
 				decoded->src.addr_mode = MODE_IMMEDIATE;
-				decoded->src.params.u8 = *(++istream);
+				decoded->src.params.immed = *(++istream) & 0xFF;
 				istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst));
 				break;
 			case 5:
@@ -295,12 +295,12 @@
 					decoded->op = M68K_EORI_CCR;
 					decoded->extra.size = OPSIZE_BYTE;
 					decoded->src.addr_mode = MODE_IMMEDIATE;
-					decoded->src.params.u8 = *(++istream);
+					decoded->src.params.immed = *(++istream) & 0xFF;
 				} else if((*istream & 0xFF) == 0x7C) {
 					decoded->op = M68K_EORI_SR;
 					decoded->extra.size = OPSIZE_WORD;
 					decoded->src.addr_mode = MODE_IMMEDIATE;
-					decoded->src.params.u16 = *(++istream);
+					decoded->src.params.immed = *(++istream);
 				} else {
 					decoded->op = M68K_EOR;
 					decoded->variant = VAR_IMMEDIATE;
@@ -311,14 +311,14 @@
 					switch (size)
 					{
 					case OPSIZE_BYTE:
-						decoded->src.params.u8 = *(++istream);
+						decoded->src.params.immed = *(++istream) & 0xFF;
 						break;
 					case OPSIZE_WORD:
-						decoded->src.params.u16 = *(++istream);
+						decoded->src.params.immed = *(++istream);
 						break;
 					case OPSIZE_LONG:
 						immed = *(++istream);
-						decoded->src.params.u32 = immed << 16 | *(++istream);
+						decoded->src.params.immed = immed << 16 | *(++istream);
 						break;
 					}
 					istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
@@ -334,14 +334,14 @@
 				switch (decoded->extra.size)
 				{
 				case OPSIZE_BYTE:
-					decoded->src.params.u8 = *(++istream);
+					decoded->src.params.immed = *(++istream) & 0xFF;
 					break;
 				case OPSIZE_WORD:
-					decoded->src.params.u16 = *(++istream);
+					decoded->src.params.immed = *(++istream);
 					break;
 				case OPSIZE_LONG:
 					immed = *(++istream);
-					decoded->src.params.u32 = (immed << 16) | *(++istream);
+					decoded->src.params.immed = (immed << 16) | *(++istream);
 					break;
 				}
 				istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
@@ -411,11 +411,11 @@
 					immed = *(++istream);
 					if(*istream & 0x400) {
 						decoded->dst.addr_mode = MODE_REG;
-						decoded->dst.params.u16 = immed;
+						decoded->dst.params.immed = immed;
 						istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src));
 					} else {
 						decoded->src.addr_mode = MODE_REG;
-						decoded->src.params.u16 = immed;
+						decoded->src.params.immed = immed;
 						istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst));
 					}
 				} else {
@@ -497,7 +497,7 @@
 							decoded->op = M68K_BKPT;
 							decoded->src.addr_mode = MODE_IMMEDIATE;
 							decoded->extra.size = OPSIZE_UNSIZED;
-							decoded->src.params.u32 = *istream & 0x7;
+							decoded->src.params.immed = *istream & 0x7;
 #endif
 							break;
 						case 0x10:
@@ -573,7 +573,7 @@
 								decoded->op = M68K_TRAP;
 								decoded->extra.size = OPSIZE_UNSIZED;
 								decoded->src.addr_mode = MODE_IMMEDIATE;
-								decoded->src.params.u32 = *istream & 0xF;
+								decoded->src.params.immed = *istream & 0xF;
 								break;
 							case 2:
 								//LINK.w
@@ -582,7 +582,7 @@
 								decoded->src.addr_mode = MODE_AREG;
 								decoded->src.params.regs.pri = *istream & 0x7;
 								decoded->dst.addr_mode = MODE_IMMEDIATE;
-								decoded->dst.params.u16 = *(++istream);
+								decoded->dst.params.immed = *(++istream);
 								break;
 							case 3:
 								//UNLK
@@ -616,7 +616,7 @@
 								case 2:
 									decoded->op = M68K_STOP;
 									decoded->src.addr_mode = MODE_IMMEDIATE;
-									decoded->src.params.u32 =*(++istream);
+									decoded->src.params.immed =*(++istream);
 									break;
 								case 3:
 									decoded->op = M68K_RTE;
@@ -625,7 +625,7 @@
 #ifdef M68010
 									decoded->op = M68K_RTD;
 									decoded->src.addr_mode = MODE_IMMEDIATE;
-									decoded->src.params.u32 =*(++istream);
+									decoded->src.params.immed =*(++istream);
 #endif
 									break;
 								case 5:
@@ -662,7 +662,7 @@
 			case 1: //DBcc
 				decoded->op = M68K_DBCC;
 				decoded->src.addr_mode = MODE_IMMEDIATE;
-				decoded->src.params.u16 = *(++istream);
+				decoded->src.params.immed = *(++istream);
 				decoded->dst.addr_mode = MODE_REG;
 				decoded->dst.params.regs.pri = *istream & 0x7;
 				break;
@@ -688,18 +688,7 @@
 			if (!immed) {
 				immed = 8;
 			}
-			switch (size)
-			{
-			case OPSIZE_BYTE:
-				decoded->src.params.u8 = immed;
-				break;
-			case OPSIZE_WORD:
-				decoded->src.params.u16 = immed;
-				break;
-			case OPSIZE_LONG:
-				decoded->src.params.u32 = immed;
-				break;
-			}
+			decoded->src.params.immed = immed;
 			if (*istream & 0x100) {
 				decoded->op = M68K_SUB;
 			} else {
@@ -724,13 +713,14 @@
 			decoded->variant = VAR_BYTE;
 			immed = sign_extend8(immed);
 		}
-		decoded->src.params.u32 = immed;
+		decoded->src.params.immed = immed;
 		break;
 	case MOVEQ:
 		decoded->op = M68K_MOVE;
 		decoded->variant = VAR_QUICK;
+		decoded->extra.size = OPSIZE_LONG;
 		decoded->src.addr_mode = MODE_IMMEDIATE;
-		decoded->src.params.u32 = sign_extend8(*istream & 0xFF);
+		decoded->src.params.immed = sign_extend8(*istream & 0xFF);
 		decoded->dst.addr_mode = MODE_REG;
 		decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream);
 		immed = *istream & 0xFF;
@@ -1012,18 +1002,7 @@
 			immed = (*istream >> 9) & 0x7;
 			if (*istream & 0x100) {
 				decoded->src.addr_mode = MODE_IMMEDIATE;
-				switch(decoded->extra.size)
-				{
-				case OPSIZE_BYTE:
-					decoded->src.params.u8 = immed;
-					break;
-				case OPSIZE_WORD:
-					decoded->src.params.u16 = immed;
-					break;
-				case OPSIZE_LONG:
-					decoded->src.params.u32 = immed;
-					break;
-				}
+				decoded->src.params.immed = immed;
 			} else {
 				decoded->src.addr_mode = MODE_REG;
 				decoded->src.params.regs.pri = immed;
@@ -1136,7 +1115,7 @@
 	"le"
 };
 
-int m68k_disasm_op(m68k_op_info *decoded, uint8_t size, char *dst, int need_comma)
+int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma)
 {
 	char * c = need_comma ? "," : "";
 	switch(decoded->addr_mode)
@@ -1154,11 +1133,11 @@
 	case MODE_AREG_DISPLACE:
 		return sprintf(dst, "%s (a%d, %d)", c, decoded->params.regs.pri, decoded->params.regs.displacement);
 	case MODE_IMMEDIATE:
-		return sprintf(dst, "%s #%d", c, (size == OPSIZE_LONG || size == OPSIZE_UNSIZED) ? decoded->params.u32 : (size == OPSIZE_WORD ? decoded->params.u16 : decoded->params.u8));
+		return sprintf(dst, "%s #%d", c, decoded->params.immed);
 	case MODE_ABSOLUTE_SHORT:
-		return sprintf(dst, "%s $%X.w", c, decoded->params.u32);
+		return sprintf(dst, "%s $%X.w", c, decoded->params.immed);
 	case MODE_ABSOLUTE:
-		return sprintf(dst, "%s $%X", c, decoded->params.u32);
+		return sprintf(dst, "%s $%X", c, decoded->params.immed);
 	case MODE_PC_DISPLACE:
 		return sprintf(dst, "%s (pc, %d)", c, decoded->params.regs.displacement);
 	default:
@@ -1166,7 +1145,7 @@
 	}
 }
 
-int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, uint8_t size, char *dst, int need_comma)
+int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma)
 {
 	int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1;
 	char *rtype, *last_rtype;
@@ -1181,7 +1160,7 @@
 		}
 		strcat(dst, " ");
 		for (oplen = 1, reg=0; bit < 16 && bit > -1; bit += dir, reg++) {
-			if (decoded->params.u16 & (1 << bit)) {
+			if (decoded->params.immed & (1 << bit)) {
 				if (reg > 7) {
 					rtype = "a";
 					regnum = reg - 8;
@@ -1214,7 +1193,7 @@
 		}
 		return oplen;
 	} else {
-		return m68k_disasm_op(decoded, size, dst, need_comma);
+		return m68k_disasm_op(decoded, dst, need_comma);
 	}
 }
 
@@ -1233,16 +1212,14 @@
 		dst[ret] = 0;
 		strcat(dst, cond_mnem[decoded->extra.cond]);
 		ret = strlen(dst);
-		size = decoded->op = M68K_BCC ? OPSIZE_LONG : OPSIZE_WORD;
 		break;
 	case M68K_BSR:
-		size = OPSIZE_LONG;
 		ret = sprintf(dst, "bsr%s", decoded->variant == VAR_BYTE ? ".s" : "");
 		break;
 	case M68K_MOVE_FROM_SR:
 		ret = sprintf(dst, "%s", mnemonics[decoded->op]);
 		ret += sprintf(dst + ret, " SR");
-		ret += m68k_disasm_op(&(decoded->dst), decoded->extra.size, dst + ret, 1);
+		ret += m68k_disasm_op(&(decoded->dst), dst + ret, 1);
 		return ret;
 	case M68K_ANDI_SR:
 	case M68K_EORI_SR:
@@ -1254,7 +1231,7 @@
 	case M68K_MOVE_CCR:
 	case M68K_ORI_CCR:
 		ret = sprintf(dst, "%s", mnemonics[decoded->op]);
-		ret += m68k_disasm_op(&(decoded->src), decoded->extra.size, dst + ret, 0);
+		ret += m68k_disasm_op(&(decoded->src), dst + ret, 0);
 		ret += sprintf(dst + ret, ", %s", special_op);
 		return ret;
 	default:
@@ -1265,13 +1242,13 @@
 				size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : "")));
 	}
 	if (decoded->op == M68K_MOVEM) {
-		op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), size, dst + ret, 0);
+		op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0);
 		ret += op1len;
-		ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), size, dst + ret, op1len);
+		ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), dst + ret, op1len);
 	} else {
-		op1len = m68k_disasm_op(&(decoded->src), size, dst + ret, 0);
+		op1len = m68k_disasm_op(&(decoded->src), dst + ret, 0);
 		ret += op1len;
-		ret += m68k_disasm_op(&(decoded->dst), size, dst + ret, op1len);
+		ret += m68k_disasm_op(&(decoded->dst), dst + ret, op1len);
 	}
 	return ret;
 }