scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit a437e6130c7c1c4dd71633b2bc55ff29ccfc2af4
parent 723680c7ffccb0b03b6795b7f5b2ad52b3d6ca43
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 21 Sep 2019 11:24:48 +0200

[as] Implement toobig()

This function checks if an immediate is valid based in a type.

Diffstat:
Msrc/cmd/as/as.h | 2++
Msrc/cmd/as/symbol.c | 21+++++++++++++++++++--
Msrc/cmd/as/target/x80/ins.c | 8++++++--
Msrc/cmd/as/target/x80/proc.h | 1-
4 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/src/cmd/as/as.h b/src/cmd/as/as.h @@ -32,6 +32,8 @@ enum common_args { ASTR, AREG, ANUMBER, + AIMM3, + AIMM5, AIMM8, AIMM16, AIMM32, diff --git a/src/cmd/as/symbol.c b/src/cmd/as/symbol.c @@ -1,6 +1,7 @@ #include <ctype.h> #include <stdio.h> #include <stdint.h> +#include <stdlib.h> #include <string.h> #include <scc/scc.h> @@ -117,8 +118,24 @@ deflabel(char *name) int toobig(Node *np, int type) { - /* TODO */ - return 0; + unsigned long long val = np->sym->value; + + switch (type) { + case AIMM3: + return val > 7; + case AIMM5: + return val > 0x1F; + case AIMM8: + return val > 0xFF; + case AIMM16: + return val > 0xFFFF; + case AIMM32: + return val > 0xFFFFFFFF; + case AIMM64: + return 1; + default: + abort(); + } } static void diff --git a/src/cmd/as/target/x80/ins.c b/src/cmd/as/target/x80/ins.c @@ -164,9 +164,10 @@ match(Op *op, Node **args) index_address: if (np->addr != AINDEX) return 0; - if (np->left->left->sym->value != arg) + np = np->left->left; + if (np->sym->value != arg) return 0; - if (toobig(np, arg)) + if (toobig(np, AIMM8)) error("overflow in index"); break; case ARST: @@ -176,6 +177,9 @@ match(Op *op, Node **args) return 0; break; case AZERO: + if (np->addr != AIMM) + return 0; + break; case AIMM3: case AIMM8: case AIMM16: diff --git a/src/cmd/as/target/x80/proc.h b/src/cmd/as/target/x80/proc.h @@ -57,7 +57,6 @@ enum args { AINDER_IX, /* (IX) */ AINDER_IY, /* (IY) */ - AIMM3, /* 3 bit immediate */ AZERO, /* a literal 0 */ ARST, /* 0h, 08h, 10h, 18h, 20h, 28h, 30h, 38h */ };