ref: 67edfb04d803788d5d55242ec0ca813048d78266
dir: /as/target/x80/ins.c/
static char sccsid[] = "@(#) ./as/target/z80/ins.c"; #include <stdlib.h> #include <string.h> #include "../../../inc/scc.h" #include "../../as.h" #include "proc.h" int rclass(int reg) { switch (reg) { case AREG_B: case AREG_C: case AREG_D: case AREG_E: case AREG_H: case AREG_L: case AREG_A: return 1; default: return 0; } } int pclass(int reg) { switch (reg) { case AREG_B: case AREG_C: case AREG_D: case AREG_E: case AREG_IXH: case AREG_IXL: case AREG_A: return 1; default: return 0; } } int qclass(int reg) { switch (reg) { case AREG_B: case AREG_C: case AREG_D: case AREG_E: case AREG_IYH: case AREG_IYL: case AREG_A: return 1; default: return 0; } } int ddclass(int reg) { switch (reg) { case AREG_BC: case AREG_DE: case AREG_HL: case AREG_SP: return 1; default: return 0; } } int qqclass(int reg) { switch (reg) { case AREG_BC: case AREG_DE: case AREG_HL: case AREG_AF: return 1; default: return 0; } } int ppclass(int reg) { switch (reg) { case AREG_BC: case AREG_DE: case AREG_IX: case AREG_SP: return 1; default: return 0; } } int rrclass(int reg) { switch (reg) { case AREG_BC: case AREG_DE: case AREG_IY: case AREG_SP: return 1; default: return 0; } } int ccclass(int reg) { switch (reg) { case AREG_NZ: case AREG_Z: case AREG_NC: case AREG_C: case AREG_PO: case AREG_PE: case AREG_P: case AREG_M: return 1; default: return 0; } } static int reg2int(int reg) { switch (reg) { case AREG_B: return 0; case AREG_C: return 1; case AREG_D: return 2; case AREG_E: return 3; case AREG_IXH: case AREG_IYH: case AREG_H: return 4; case AREG_IXL: case AREG_IYL: case AREG_L: return 5; case AREG_A: return 7; case AREG_BC: return 0; case AREG_DE: return 1; case AREG_HL: case AREG_IX: case AREG_IY: return 2; case AREG_AF: case AREG_SP: return 3; default: abort(); } } static int flag2int(int flag) { switch (flag) { case AREG_NZ: return 0; case AREG_Z: return 1; case AREG_NC: return 2; case AREG_C: return 3; case AREG_PO: return 4; case AREG_PE: return 5; case AREG_P: return 6; case AREG_M: return 7; default: abort(); } } void r8_imm8(Op *op, Node **args) { Node *par1, *par2; unsigned char buf[3]; int n = op->size; par1 = args[0]; par2 = args[1]; memcpy(buf, op->bytes, n); buf[n-1] = par2->sym->value; buf[n-2] |= reg2int(par1->sym->argtype) << 3; emit(buf, n); } void r8_idx(Op *op, Node **args) { args[1] = args[1]->left; r8_imm8(op, args); } void idx_r8(Op *op, Node **args) { Node *par1, *par2; unsigned char buf[3]; int n = op->size; par1 = args[0]->left; par2 = args[1]; memcpy(buf, op->bytes, n); buf[n-1] = par1->sym->value; buf[n-2] |= reg2int(par2->sym->argtype); emit(buf, n); } void idx_imm8(Op *op, Node **args) { Node *par1, *par2; unsigned char buf[3]; int n = op->size; par1 = args[0]->left; par2 = args[1]; memcpy(buf, op->bytes, n); buf[n-1] = par1->sym->value; buf[n-2] = par2->sym->value; emit(buf, n); } void imm8(Op *op, Node **args) { Node *par1, *par2; unsigned char buf[3]; int n = op->size; par2 = args[1]; memcpy(buf, op->bytes, n); buf[n-1] = par2->sym->value; emit(buf, n); } void imm16(Op *op, Node **args) { Node *imm; unsigned char buf[4]; unsigned val; int n = op->size; imm = (args[1]) ? args[1] : args[0]; memcpy(buf, op->bytes, n); val = imm->sym->value; buf[n-1] = val >> 8; buf[n-2] = val; emit(buf, n); } void dir(Op *op, Node **args) { Node *dir; dir = (args[1]->addr == ADIRECT) ? args[1] : args[0]; args[1] = dir->left; imm16(op, args); } void r8_r8(Op *op, Node **args) { Node *par1, *par2; unsigned char buf[3]; int n = op->size; par1 = args[0]; par2 = args[1]; memcpy(buf, op->bytes, n); buf[n-1] |= reg2int(par1->sym->argtype) << 3 | reg2int(par2->sym->argtype); emit(buf, n); } void r8(Op *op, Node **args) { Node *par; unsigned char buf[3]; int n = op->size; par = args[0]; memcpy(buf, op->bytes, n); buf[n-1] |= reg2int(par->sym->argtype); emit(buf, n); } void xx_r8(Op *op, Node **args) { args[0] = args[1]; r8(op, args); } void r8_xx(Op *op, Node **args) { Node *par; unsigned char buf[3]; int n = op->size; par = args[0]; memcpy(buf, op->bytes, n); buf[n-1] |= reg2int(par->sym->argtype) << 3; emit(buf, n); } void r16_xx(Op *op, Node **args) { Node *par; unsigned char buf[4]; int n = op->size; par = args[0]; memcpy(buf, op->bytes, n); buf[n-1] |= reg2int(par->sym->argtype) << 4; emit(buf, n); } void xx_r16(Op *op, Node **args) { args[0] = args[1]; r16_xx(op, args); } void r16_imm16(Op *op, Node **args) { Node *par1, *par2; unsigned char buf[4]; int n = op->size; unsigned val; par1 = args[0]; par2 = args[1]; memcpy(buf, op->bytes, n); val = par2->sym->value; buf[n-1] = val >> 8; buf[n-2] = val; buf[n-3] |= reg2int(par1->sym->argtype) << 4; emit(buf, n); } void r16_dir(Op *op, Node **args) { Node *dir, *reg; if (args[1]->addr == ADIRECT) dir = args[1], reg = args[0]; else dir = args[0], reg = args[1]; args[0] = reg; args[1] = dir->left; r16_imm16(op, args); } void idx(Op *op, Node **args) { Node *imm; unsigned char buf[4]; int n = op->size; imm = args[0]->left->right; memcpy(buf, op->bytes, n); buf[n-1] = imm->sym->value; emit(buf, n); } void im(Op *op, Node **args) { unsigned val = args[0]->sym->value; unsigned char buf[4]; int n = op->size; if (val > 0) ++val; memcpy(buf, op->bytes, n); buf[n-1] |= val << 3; emit(buf, n); } void r_bit(Op *op, Node **args) { Node *par1, *par2; unsigned char buf[4]; int n = op->size; par1 = args[0]; par2 = args[1]; memcpy(buf, op->bytes, n); buf[n-1] |= reg2int(par2->sym->argtype) | par1->sym->value << 3; emit(buf, n); } void r_idx_bit(Op *op, Node **args) { /* TODO */ abort(); } void bit(Op *op, Node **args) { Node *par; unsigned char buf[2]; unsigned val; int n = op->size; val = args[0]->sym->value; memcpy(buf, op->bytes, n); buf[n-1] |= val << 3; emit(buf, n); } void idx_bit(Op *op, Node **args) { /* TODO */ abort(); } void cc(Op *op, Node **args) { unsigned char buf[4]; Node *flag, *imm; int n = op->size, i = n; unsigned val; flag = args[0]; imm = args[1]; memcpy(buf, op->bytes, n); if (imm) { val = imm->sym->value; buf[--i] = val >> 8; buf[--i] = val; } buf[--i] |= flag2int(flag->sym->argtype) << 3; emit(buf, n); } void jr(Op *op, Node **args) { /* TODO */ abort(); } void rst(Op *op, Node **args) { unsigned char buf[1]; buf[0] = op->bytes[0]; buf[0] |= args[0]->sym->value; emit(buf, 1); }