shithub: scc

Download patch

ref: 50d06031f803ff69ea1b44995d3bc47c6abc45ca
parent: e03e4140667f946d8f849adfb330a058008d331c
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu May 17 11:53:45 EDT 2018

[as/x86] Add basic support for register classification

This patch adds the basic infraestructure needed in as to be able
to classify registers based in class registers.

--- a/as/target/x86/ins.c
+++ b/as/target/x86/ins.c
@@ -6,35 +6,215 @@
 #include "../../as.h"
 #include "proc.h"
 
+static int
+getclass(Node *np)
+{
+	if (np->addr != AREG)
+		return 0;
+
+	switch (np->sym->value) {
+	case AREG_AL:
+	case AREG_AH:
+	case AREG_BL:
+	case AREG_BH:
+	case AREG_CL:
+	case AREG_CH:
+	case AREG_DL:
+	case AREG_DH:
+		return R8CLASS;
+
+	case AREG_CS:
+	case AREG_DS:
+	case AREG_SS:
+	case AREG_ES:
+	case AREG_FS:
+	case AREG_GS:
+
+	case AREG_EFLAGS:
+	case AREG_CF:
+	case AREG_PF:
+	case AREG_AF:
+	case AREG_ZF:
+	case AREG_SF:
+	case AREG_TF:
+	case AREG_IF:
+	case AREG_DF:
+	case AREG_OF:
+	case AREG_IOPL:
+	case AREG_NT:
+	case AREG_RF:
+	case AREG_VM:
+	case AREG_AC:
+	case AREG_VIF:
+	case AREG_VIP:
+	case AREG_ID:
+
+	case AREG_AX:
+	case AREG_EAX:
+	case AREG_RAX:
+
+	case AREG_BX:
+	case AREG_EBX:
+	case AREG_RBX:
+
+	case AREG_CX:
+	case AREG_ECX:
+	case AREG_RCX:
+
+	case AREG_DX:
+	case AREG_EDX:
+	case AREG_RDX:
+
+	case AREG_SI:
+	case AREG_SIL:
+	case AREG_ESI:
+	case AREG_RSI:
+	case AREG_DI:
+	case AREG_DIL:
+	case AREG_EDI:
+	case AREG_RDI:
+
+	case AREG_SP:
+	case AREG_SPL:
+	case AREG_ESP:
+	case AREG_RSP:
+
+	case AREG_BP:
+	case AREG_BPL:
+	case AREG_EBP:
+	case AREG_RBP:
+
+	case AREG_R0:
+	case AREG_MM0:
+	case AREG_R1:
+	case AREG_MM1:
+	case AREG_R2:
+	case AREG_MM2:
+	case AREG_R3:
+	case AREG_MM3:
+	case AREG_R4:
+	case AREG_MM4:
+	case AREG_R5:
+	case AREG_MM5:
+	case AREG_R6:
+	case AREG_MM6:
+	case AREG_R7:
+	case AREG_MM7:
+
+	case AREG_R8:
+	case AREG_R8L:
+	case AREG_R8W:
+	case AREG_R9:
+	case AREG_R9L:
+	case AREG_R9W:
+	case AREG_R10:
+	case AREG_R10L:
+	case AREG_R10W:
+	case AREG_R11:
+	case AREG_R11L:
+	case AREG_R11W:
+	case AREG_R12:
+	case AREG_R12L:
+	case AREG_R12W:
+	case AREG_R13:
+	case AREG_R13L:
+	case AREG_R13W:
+	case AREG_R14:
+	case AREG_R14L:
+	case AREG_R14W:
+	case AREG_R15:
+	case AREG_R15L:
+	case AREG_R15W:
+
+	case AREG_XMM0:
+	case AREG_XMM1:
+	case AREG_XMM2:
+	case AREG_XMM3:
+	case AREG_XMM4:
+	case AREG_XMM5:
+	case AREG_XMM6:
+	case AREG_XMM7:
+	case AREG_XMM8:
+	case AREG_XMM9:
+	case AREG_XMM10:
+	case AREG_XMM11:
+	case AREG_XMM12:
+	case AREG_XMM13:
+	case AREG_XMM14:
+	case AREG_XMM15:
+
+	case AREG_YMM0:
+	case AREG_YMM1:
+	case AREG_YMM2:
+	case AREG_YMM3:
+	case AREG_YMM4:
+	case AREG_YMM5:
+	case AREG_YMM6:
+	case AREG_YMM7:
+	case AREG_YMM8:
+	case AREG_YMM9:
+	case AREG_YMM10:
+	case AREG_YMM11:
+	case AREG_YMM12:
+	case AREG_YMM13:
+	case AREG_YMM14:
+	case AREG_YMM15:
+
+	case AREG_MXCSR:
+		return 0;
+	default:
+		abort();
+	}
+}
+
 int
 match(Op *op, Node **args)
 {
 	unsigned char *p;
-	int a, olda;
+	int arg, class;
+	Node *np;
 
 	if (!op->args)
 		return args == NULL;
 
-	for (p = op->args; *p; ++p) {
-		if (*p != AREP)
-			a = *p;
-		else
+	for (p = op->args; arg = *p; ++p) {
+		if (arg & AREP)
 			--p;
+		if ((np = *args++) == NULL)
+			return (arg & (AREP|AOPT)) != 0;
 
-		switch (a) {
+		arg &= ~(AREP|AOPT);
+		switch (arg) {
+		case AREG_R8CLASS:
+			class = R8CLASS;
+		check_class:
+			if ((getclass(np) & class) == 0)
+				return 0;
+			break;
 		case AIMM8:
 		case AIMM16:
 		case AIMM32:
 		case AIMM64:
-		case AREG_AL:
-		case AREG_AH:
-		case AREG_AX:
-		case AREG_EAX:
+			if (np->addr != AIMM)
+				return 0;
+			if (toobig(np, arg))
+				error("overflow in immediate operand");
+			break;
+		case ASYM:
+			if (np->addr != AIMM || np->op != IDEN)
+				return 0;
+			break;
+		case ADIRECT:
+		case ASTR:
+			if (np->addr != arg)
+				return 0;
+			break;
 		default:
 			abort();
 		}
 	}
-	return 1;
+
+	return *args == NULL;
 }
 
 Node *
--- a/as/target/x86/proc.h
+++ b/as/target/x86/proc.h
@@ -146,9 +146,10 @@
 	AREG_YMM15,
 
 	AREG_MXCSR,
+
+	AREG_R8CLASS,   /* register class for 8 bit registers in i286 */
 };
 
 enum {
-	AREG8,
-	AREG16,
+	R8CLASS = 1 << 0,
 };