summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/PCodeInfo.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/PCodeInfo.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz
MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/PCodeInfo.c')
-rw-r--r--compiler_and_linker/unsorted/PCodeInfo.c1354
1 files changed, 0 insertions, 1354 deletions
diff --git a/compiler_and_linker/unsorted/PCodeInfo.c b/compiler_and_linker/unsorted/PCodeInfo.c
deleted file mode 100644
index b2e2385..0000000
--- a/compiler_and_linker/unsorted/PCodeInfo.c
+++ /dev/null
@@ -1,1354 +0,0 @@
-#include "compiler/PCodeInfo.h"
-#include "compiler/CError.h"
-#include "compiler/CMangler.h"
-#include "compiler/CParser.h"
-#include "compiler/Alias.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeListing.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/StackFrame.h"
-#include "compiler/TOC.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-#pragma pool_strings on
-
-int pcode_bad_operand;
-char *orig_buf;
-static int do_show_basic_blocks;
-
-void pcode_get_hi_lo(int bits, char typechar, SInt32 *hi, SInt32 *lo) {
- if (bits == 0) {
- *hi = 0;
- *lo = 0;
- return;
- }
- if (bits == 32) {
- *hi = 0x7FFFFFFF;
- *lo = -0x80000000;
- return;
- }
-
- if (bits < 32 && bits > 0) {
- switch (typechar) {
- case 'u':
- *hi = (1 << bits) - 1;
- *lo = 0;
- break;
- case 'i':
- case 'x':
- *hi = (1 << bits) - 1;
- *lo = -(1 << (bits - 1));
- break;
- default:
- *hi = (1 << (bits - 1)) - 1;
- *lo = -(1 << (bits - 1));
- }
- } else {
- CError_FATAL(65);
- }
-}
-
-int pcode_check_imm_bits(SInt32 value, int bits, char typechar) {
- char buf[2];
- int forcedBits;
- SInt32 r6;
- SInt32 r0;
-
- forcedBits = 0;
- if (bits >= 0 && bits < 32) {
- if (bits == 0) {
- r6 = 0;
- r0 = 0;
- } else {
- switch (typechar) {
- case 'u':
- r6 = (1 << bits) - 1;
- r0 = 0;
- break;
- case 'i':
- case 'x':
- r6 = (1 << bits) - 1;
- r0 = -(1 << (bits - 1));
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- buf[0] = typechar;
- buf[1] = 0;
- forcedBits = atoi(buf);
- default:
- r6 = (1 << (bits - 1)) - 1;
- r0 = -(1 << (bits - 1));
- }
- }
-
- if ((value < r0) || (value > r6))
- return 1;
- if (forcedBits > 0 && value != ((value >> forcedBits) << forcedBits))
- return 1;
- } else if (bits > 32) {
- CError_FATAL(110);
- }
-
- return 0;
-}
-
-int pcode_const_from_format(const char *format, SInt32 *pResult) {
- char buf[32];
- int len = 0;
-
- for (len = 0; len < 30 && isdigit(format[len]); len++) {
- buf[len] = format[len];
- }
- buf[len] = 0;
-
- *pResult = atoi(buf);
- return len;
-}
-
-PCode *vformatpcode(short opcode, va_list argList) {
- // has many wrong registers but probably ok otherwise
- int argcount; // r29
- OpcodeInfo *info; // r27 for a short time
- int effect; // r27
- const char *format; // r26
- PCode *pcode; // r25
- PCodeArg *arg; // r24
- int unkreg_r23; // r23
- int unkreg_r22; // r22
- PCodeArg *lastArg; // r21
- int pcode_size; // r20 for a short time
- int tmp;
- int tmp2; // r19
- int i;
- SInt32 thing;
- SInt32 thing2;
- SInt32 thing3;
- SInt32 thing4;
- Object *obj;
- PCodeLabel *label;
- char c;
-
- info = &opcodeinfo[opcode];
- format = info->format;
- argcount = info->x8;
- unkreg_r23 = 0;
- unkreg_r22 = 0;
-
- if (format[0] == '#') {
- unkreg_r23 = va_arg(argList, int);
- argcount += unkreg_r23;
- format++;
- }
-
- if (info->flags & fCanSetRecordBit)
- unkreg_r22 = 1;
-
- if ((argcount + unkreg_r22) < 5)
- unkreg_r22 += 5 - (argcount + unkreg_r22);
-
- pcode_size = (argcount + unkreg_r22) * sizeof(PCodeArg) + sizeof(PCode);
- pcode = lalloc(pcode_size);
- memclrw(pcode, pcode_size);
-
- pcode->op = opcode;
- pcode->argCount = argcount;
- pcode->flags = info->flags;
- lastArg = pcode->args + pcode->argCount;
- arg = pcode->args;
- while (*format) {
- if (arg >= lastArg)
- CError_FATAL(189);
-
- if (*format == ',' || *format == ';')
- format++;
- if (*format == '[' || *format == '(')
- format++;
-
- effect = EffectRead;
- if (*format == '=') {
- effect = EffectWrite;
- format++;
- } else if (*format == '+') {
- effect = EffectRead | EffectWrite;
- format++;
- }
-
- if (*format == '-')
- format++;
- if (*format == '?')
- format++;
- if (*format == '!')
- format++;
-
- switch ((c = *format)) {
- case 'b':
- tmp = va_arg(argList, int);
- if (!tmp)
- effect = 0;
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_GPR;
- arg->data.reg.reg = tmp;
- arg->data.reg.effect = effect;
- break;
- case 'r':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_GPR;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- break;
- case 'f':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_FPR;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- break;
- case 'v':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_VR;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- break;
- case 'c':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_CRFIELD;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- break;
- case 'C':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = 2;
- arg->data.reg.effect = effect;
- break;
- case 'L':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = 1;
- arg->data.reg.effect = effect;
- break;
- case 'V':
- i = unkreg_r23;
- while (i > 0) {
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_GPR;
- arg->data.reg.reg = 31 - --i;
- arg->data.reg.effect = effect;
- arg++;
- }
- arg--;
- break;
- case 'X':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = 0;
- arg->data.reg.effect = effect;
- break;
- case 'Y':
- if (pcode->op == PC_MTCRF) {
- tmp = pcode->args[0].data.imm.value;
- for (i = 0; i < 8; i++) {
- if (tmp & (0x80 >> i)) {
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_CRFIELD;
- arg->data.reg.reg = i;
- arg->data.reg.effect = EffectWrite;
- arg++;
- }
- }
- } else {
- i = 0;
- while (i < 8) {
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_CRFIELD;
- arg->data.reg.reg = i++;
- arg->data.reg.effect = EffectRead;
- arg++;
- }
- }
- arg--;
- break;
- case 'Z':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_CRFIELD;
- arg->data.reg.reg = 0;
- arg->data.reg.effect = effect;
- break;
- case 'P':
- if (isdigit(format[1]))
- format += pcode_const_from_format(format + 1, &thing);
- else
- CError_FATAL(319);
- case 's':
- tmp = va_arg(argList, int);
- tmp2 = -1;
- for (i = 0; i < 4; i++) {
- if (tmp == spr_to_sysreg[i]) {
- tmp2 = i;
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = i;
- arg->data.reg.effect = effect;
- if ((effect & EffectWrite) && (tmp == 0x100))
- pcsetsideeffects(pcode);
- break;
- }
- }
-
- if (tmp2 < 0) {
- pcsetsideeffects(pcode);
- arg->kind = PCOp_SYSREG;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = tmp;
- arg->data.reg.effect = effect;
- }
-
- break;
-
- case 'T':
- tmp = va_arg(argList, int);
- if (tmp == 0x10C) {
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = 0x11C;
- arg->data.reg.effect = effect;
- } else if (tmp == 0x10D) {
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = 0x11D;
- arg->data.reg.effect = effect;
- } else {
- CError_FATAL(353);
- }
- pcsetsideeffects(pcode);
- arg->kind = PCOp_SYSREG;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- break;
-
- case 'S':
- tmp2 = -1;
- if (isdigit(format[1]))
- format += pcode_const_from_format(format + 1, &thing2);
- else
- CError_FATAL(371);
-
- for (i = 0; i < 4; i++) {
- if (thing2 == spr_to_sysreg[i]) {
- tmp2 = i;
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = i;
- arg->data.reg.effect = effect;
- if ((effect & EffectWrite) && (thing2 == 0x100))
- pcsetsideeffects(pcode);
- break;
- }
- }
-
- if (tmp2 < 0) {
- pcsetsideeffects(pcode);
- arg->kind = PCOp_SYSREG;
- arg->arg = RegClass_SPR;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- }
- break;
-
- case 'a':
- case 'i':
- case 'n':
- case 'u':
- case 'w':
- case 'x':
- tmp2 = (unsigned char) c;
- thing3 = 16;
- if (*format == 'a') {
- if (isdigit(format[1]))
- tmp2 = (unsigned char) *(++format);
- else
- CError_FATAL(408);
- }
- if (isdigit(format[1])) {
- format += pcode_const_from_format(format + 1, &thing3);
- }
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, int);
- arg->data.imm.obj = NULL;
- if (pcode_check_imm_bits(arg->data.imm.value, thing3, tmp2))
- CError_FATAL(419);
- break;
-
- case 'N':
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, int);
- arg->data.imm.obj = NULL;
- if (pcode_check_imm_bits(arg->data.imm.value, 6, 'u'))
- CError_FATAL(429);
- break;
-
- case 'D':
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, int);
- arg->data.imm.obj = NULL;
- if (pcode_check_imm_bits(arg->data.imm.value, 10, 'u'))
- CError_FATAL(438);
- break;
-
- case 'B':
- case 't':
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, int);
- arg->data.imm.obj = NULL;
- if (pcode_check_imm_bits(arg->data.imm.value, 5, 'u'))
- CError_FATAL(448);
- break;
-
- case 'Q':
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_CRFIELD;
- arg->data.reg.reg = va_arg(argList, int);
- arg->data.reg.effect = effect;
- arg++;
- case 'q':
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, int);
- arg->data.imm.obj = NULL;
- if (pcode_check_imm_bits(arg->data.imm.value, 4, 'u'))
- CError_FATAL(463);
- break;
-
- case 'l':
- if ((label = va_arg(argList, PCodeLabel *))) {
- arg->kind = PCOp_LABEL;
- arg->data.label.label = label;
- } else {
- arg->kind = PCOp_MEMORY;
- obj = va_arg(argList, Object *);
- CError_ASSERT(476, obj->otype == OT_OBJECT);
- arg->data.mem.obj = obj;
- arg->data.mem.offset = 0;
- arg->arg = RefType_4;
- }
- break;
-
- case 'd':
- CError_ASSERT(490, format[1] == '(');
- effect = EffectRead;
- format += 2;
- if (*format == '=') {
- effect = EffectWrite;
- format++;
- } else if (*format == '+') {
- effect = EffectRead | EffectWrite;
- format++;
- }
-
- CError_ASSERT(502, format[0] == 'b');
-
- tmp = va_arg(argList, int);
- if (tmp == 0)
- effect = 0;
- arg->kind = PCOp_REGISTER;
- arg->arg = RegClass_GPR;
- arg->data.reg.reg = tmp;
- arg->data.reg.effect = effect;
- arg++;
-
- case 'm':
- obj = va_arg(argList, Object *);
- if (obj) {
- CError_ASSERT(515, obj->otype == OT_OBJECT);
-
- if (obj->datatype == DABSOLUTE) {
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.obj = obj;
- arg->data.imm.value = va_arg(argList, SInt32);
- } else {
- arg->kind = PCOp_MEMORY;
- arg->data.mem.obj = obj;
- arg->data.mem.offset = va_arg(argList, SInt32);
-
- if (pcode->flags & (fIsRead | fIsWrite | fPCodeFlag20000 | fPCodeFlag40000)) {
- pcode->alias = make_alias(obj, arg->data.mem.offset, nbytes_loaded_or_stored_by(pcode));
- if (is_volatile_object(obj))
- pcode->flags |= fIsVolatile;
- //if ((obj->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_CONST) : (obj->qual & Q_CONST))
- if (OBJ_GET_TARGET_CONST(obj))
- pcode->flags |= fIsConst;
- } else {
- if (pcode->op == PC_ADDI)
- pcode->alias = make_alias(obj, arg->data.mem.offset, 1);
- }
- CError_ASSERT(536, obj->datatype == DLOCAL || arg->data.mem.offset == 0);
- if (pcode->flags & (fIsRead | fIsWrite)) {
- //if ((obj->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_VOLATILE) : (obj->qual & Q_VOLATILE))
- if (OBJ_GET_TARGET_VOLATILE(obj))
- pcode->flags |= fIsVolatile;
- //if ((obj->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_CONST) : (obj->qual & Q_CONST))
- if (OBJ_GET_TARGET_CONST(obj))
- pcode->flags |= fIsConst;
- }
-
- if (pcode->flags & (fIsBranch | fIsCall)) {
- arg->arg = RefType_4;
- } else if (obj->datatype == DLOCAL) {
- if (!local_is_16bit_offset(obj))
- arg->arg = RefType_D;
- else
- arg->arg = RefType_1;
- } else {
- arg->arg = RefType_6;
- }
- }
- } else {
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, SInt32);
- arg->data.imm.obj = NULL;
- if (pcode->flags & (fIsRead | fIsWrite))
- pcode->flags |= fIsPtrOp;
- }
- break;
-
- case 'M':
- obj = va_arg(argList, Object *);
- if (obj) {
- CError_ASSERT(578, obj->otype == OT_OBJECT);
-
- if (obj->datatype == DABSOLUTE) {
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.obj = obj;
- arg->data.imm.value = va_arg(argList, SInt32);
- } else {
- arg->kind = PCOp_MEMORY;
- arg->data.mem.obj = obj;
- arg->data.mem.offset = va_arg(argList, SInt32);
-
- CError_ASSERT(590, obj->datatype == DLOCAL || arg->data.mem.offset == 0);
- if (pcode->flags & (fIsRead | fIsWrite)) {
- //if ((obj->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_VOLATILE) : (obj->qual & Q_VOLATILE))
- if (OBJ_GET_TARGET_VOLATILE(obj))
- pcode->flags |= fIsVolatile;
- //if ((obj->type->type == TYPEPOINTER || obj->type->type == TYPEARRAY) ? (TYPE_POINTER(obj->type)->qual & Q_CONST) : (obj->qual & Q_CONST))
- if (OBJ_GET_TARGET_CONST(obj))
- pcode->flags |= fIsConst;
- }
-
- if (obj->datatype == DLOCAL) {
- arg->arg = RefType_C;
- } else {
- arg->arg = RefType_8;
- }
- }
- } else {
- arg->kind = PCOp_IMMEDIATE;
- arg->data.imm.value = va_arg(argList, SInt32);
- arg->data.imm.obj = NULL;
- if (pcode->flags & (fIsRead | fIsWrite))
- pcode->flags |= fIsPtrOp;
- }
- break;
-
- case 'p':
- arg->kind = PCOp_PLACEHOLDEROPERAND;
- break;
-
- case 'O':
- arg--;
- break;
-
- default:
- CError_FATAL(629);
- }
-
- while (format[1] && strchr("/<>|*", format[1])) {
- switch (*(++format)) {
- case '/':
- if (format[1] == '2')
- format++;
- break;
- case '<':
- case '*':
- case '|':
- case '>':
- if (format[1] == 'p')
- format++;
- else if (isdigit(format[1]))
- format += pcode_const_from_format(format + 1, &thing4);
- else
- CError_FATAL(659);
- break;
- }
- }
-
- if ((c = *(++format)) == ']' || c == ')')
- format++;
- arg++;
- }
-
- while (arg < lastArg) {
- arg->kind = PCOp_PLACEHOLDEROPERAND;
- arg++;
- }
- while (unkreg_r22) {
- arg->kind = PCOp_PLACEHOLDEROPERAND;
- arg++;
- unkreg_r22--;
- }
- return pcode;
-}
-
-int expectandformatoperand(PCodeArg *operand, PCOpKind expectedKind, char a3, int bitCount, char *buf) {
- int errorlen;
- char *name;
- int tmp;
- int regclass;
- int refis1;
- int b_null;
-
- errorlen = 0;
-
- if (operand->kind != expectedKind) {
- char *kindstr;
- switch (expectedKind) {
- case PCOp_REGISTER: kindstr = "REGISTER"; break;
- case PCOp_SYSREG: kindstr = "SYSREG"; break;
- case PCOp_IMMEDIATE: kindstr = "IMMEDIATE"; break;
- case PCOp_MEMORY: kindstr = "MEMORY"; break;
- case PCOp_LABEL: kindstr = "LABEL"; break;
- case PCOp_LABELDIFF: kindstr = "LABELDIFF"; break;
- case PCOp_PLACEHOLDEROPERAND: kindstr = "PLACEHOLDEROPERAND"; break;
- default: kindstr = "unknown kind";
- }
- tmp = sprintf(buf, "{EXPECTED %s}", kindstr);
- errorlen += tmp;
- buf += tmp;
- pclist_bad_operand = 1;
- }
-
- switch (operand->kind) {
- case PCOp_REGISTER:
- if (operand->arg != (regclass = a3)) {
- tmp = sprintf(buf, "{EXPECTED %s}", register_class_name[regclass]);
- errorlen += tmp;
- buf += tmp;
- }
- if (operand->data.reg.reg < n_real_registers[regclass] && (name = special_register_names[operand->arg][operand->data.reg.reg]))
- tmp = sprintf(buf, "%s", name);
- else
- tmp = sprintf(buf, register_class_format[operand->arg], operand->data.reg.reg);
- errorlen += tmp;
- break;
- case PCOp_SYSREG:
- if (operand->arg != RegClass_SPR) {
- tmp = sprintf(buf, "{EXPECTED %s}", register_class_name[RegClass_SPR]);
- errorlen += tmp;
- buf += tmp;
- }
- tmp = sprintf(buf, register_class_format[RegClass_SPR], operand->data.reg.reg);
- errorlen += tmp;
- break;
- case PCOp_IMMEDIATE:
- switch (a3) {
- case 'x':
- tmp = sprintf(buf, "0x%x", operand->data.imm.value);
- break;
- case 'u':
- tmp = sprintf(buf, "%u", operand->data.imm.value);
- break;
- default:
- tmp = sprintf(buf, "%" PRId32, operand->data.imm.value);
- break;
- }
- errorlen += tmp;
- buf += tmp;
- if (operand->data.imm.obj) {
- name = CMangler_GetLinkName(operand->data.imm.obj)->name;
- if (strlen(name) > 50)
- tmp = sprintf(buf, "{%45.45s...}", name);
- else
- tmp = sprintf(buf, "{%s}", name);
- errorlen += tmp;
- buf += tmp;
- }
- if (pcode_check_imm_bits(operand->data.imm.value, bitCount, (char) a3)) {
- errorlen += sprintf(buf, "{IMM too large %i bits}", bitCount);
- pclist_bad_operand = 1;
- }
- break;
- case PCOp_MEMORY:
- switch ((unsigned char) operand->arg) {
- case RefType_0:
- case RefType_1:
- case RefType_2:
- case RefType_3:
- case RefType_4:
- case RefType_5:
- case RefType_9:
- break;
- case RefType_8:
- case RefType_B:
- case RefType_C:
- tmp = sprintf(buf, "HA(");
- errorlen += tmp;
- buf += tmp;
- break;
- case RefType_7:
- tmp = sprintf(buf, "HI(");
- errorlen += tmp;
- buf += tmp;
- break;
- case RefType_6:
- case RefType_A:
- case RefType_D:
- tmp = sprintf(buf, "LO(");
- errorlen += tmp;
- buf += tmp;
- break;
- default:
- tmp = sprintf(buf, "{UNEXPECTED reftype = %d}", (unsigned char) operand->arg);
- errorlen += tmp;
- buf += tmp;
- }
- name = CMangler_GetLinkName(operand->data.mem.obj)->name;
- if (strlen(name) == 0 || strlen(name) > 3200 || name[0] < 0)
- CError_FATAL(849);
- if (strlen(name) > 50)
- tmp = sprintf(buf, "%45.45s...", name);
- else
- tmp = sprintf(buf, "%s", name);
- errorlen += tmp;
- buf += tmp;
- if (operand->data.mem.offset > 0)
- tmp = sprintf(buf, "+%d", operand->data.mem.offset);
- else if (operand->data.mem.offset != 0)
- tmp = sprintf(buf, "-%d", -operand->data.mem.offset);
- else
- tmp = 0;
- errorlen += tmp;
- buf += tmp;
- if (copts.codegen_pic && uses_globals && pic_base_reg) {
- tmp = sprintf(buf, "-B%d", pic_base_pcodelabel->block->blockIndex);
- errorlen += tmp;
- buf += tmp;
- }
- switch ((unsigned char) operand->arg) {
- case RefType_6:
- case RefType_7:
- case RefType_8:
- case RefType_A:
- case RefType_B:
- case RefType_C:
- case RefType_D:
- errorlen += sprintf(buf, ")");
- }
- break;
- case PCOp_LABEL:
- if (do_show_basic_blocks) {
- if (!operand->data.label.label->block)
- tmp = sprintf(buf, "B<unknown>");
- else
- tmp = sprintf(buf, "B%" PRId32, operand->data.label.label->block->blockIndex);
- } else {
- tmp = sprintf(buf, "%.8" PRIX32, operand->data.label.label->block->codeOffset);
- }
- errorlen += tmp;
- break;
- case PCOp_LABELDIFF:
- refis1 = ((unsigned char) operand->arg == 1);
- b_null = !operand->data.labeldiff.labelB->block;
- if (operand->data.labeldiff.labelA->block == NULL) {
- if (b_null)
- tmp = sprintf(buf, "%sB<unknown>-B<unknown>+%" PRId32, refis1 ? "-" : "", operand->data.labeldiff.offset);
- else
- tmp = sprintf(buf, "%sB<unknown>-B%" PRId32 "+%" PRId32, refis1 ? "-" : "", operand->data.labeldiff.labelB->block->blockIndex, operand->data.labeldiff.offset);
- } else {
- if (b_null)
- tmp = sprintf(buf, "%sB%" PRId32 "-B<unknown>+%" PRId32, refis1 ? "-" : "", operand->data.labeldiff.labelA->block->blockIndex, operand->data.labeldiff.offset);
- else
- tmp = sprintf(buf, "%sB%" PRId32 "-B%" PRId32 "+%" PRId32, refis1 ? "-" : "", operand->data.labeldiff.labelA->block->blockIndex, operand->data.labeldiff.labelB->block->blockIndex, operand->data.labeldiff.offset);
- }
- errorlen += tmp;
- break;
- case PCOp_PLACEHOLDEROPERAND:
- errorlen += sprintf(buf, "{placeholder}");
- break;
- default:
- errorlen += sprintf(buf, "{UNEXPECTED kind = %d}", operand->kind);
- }
-
- return errorlen;
-}
-
-int formatoperand(PCodeArg *operand, char *buf) {
- return expectandformatoperand(
- operand,
- operand->kind,
- (operand->kind == PCOp_REGISTER) ? operand->arg : 'x',
- -1,
- buf);
-}
-
-void formatoperands(PCode *pcode, char *buf, int showBasicBlocks) {
- const char *format; // r29
- // there might be a PCodeArg *arg in r28
- // not sure lol
- PCodeArg *pa;
- int arg_index; // r27
-
- char *name;
- int i;
- int tmp;
- int tmp2;
- SInt32 thing;
- SInt32 thing2;
- SInt32 thing4;
- char c;
- int flagSetT;
- int flagSetF;
-
- static char *cc[] = {
- "lt", "gt", "eq", "un"
- };
- static char *to[] = {
- "", "lgt", "llt", "",
- "eq", "lge", "lle", "",
- "gt", "", "", "",
- "ge", "", "", "",
- "lt", "", "", "",
- "le", "", "", "",
- "ne", "", "", "",
- "", "", ""
- };
-
- format = opcodeinfo[pcode->op].format;
- orig_buf = buf;
- do_show_basic_blocks = showBasicBlocks;
-
- if (format[0] == '#') {
- format++;
- if (format[0] == ',')
- format++;
- }
-
- arg_index = 0;
- pa = pcode->args;
- while (*format) {
- if (*format == ';')
- break;
- if (arg_index == pcode->argCount) {
- pclist_bad_operand = 1;
- buf += sprintf(buf, "{EXCEDED noperands, remaning format = %s}", format);
- break;
- }
-
- if (*format == ',') {
- *(buf++) = ',';
- format++;
- }
-
- if (*format == '[' || *format == '(') {
- *(buf++) = *format;
- format++;
- }
-
- if (*format == '=' || *format == '+')
- format++;
- if (*format == '-')
- format++;
-
- if (*format == '?') {
- format++;
- if (*format != 'c')
- *(buf++) = ',';
- }
-
- if (*format == '!')
- format++;
-
- switch (*format) {
- case 'b':
- if (pa->kind == PCOp_REGISTER && pa->arg == RegClass_GPR && pa->data.reg.reg == 0) {
- if (pa->data.reg.effect & EffectWrite) {
- pclist_bad_operand = 1;
- buf += sprintf(buf, "!!!r");
- }
- buf += sprintf(buf, "0");
- break;
- }
- case 'r':
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_GPR, -1, buf);
- break;
- case 'f':
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_FPR, -1, buf);
- break;
- case 'v':
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_VR, -1, buf);
- break;
- case 'c':
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_CRFIELD, -1, buf);
- break;
- case 'X':
- CError_ASSERT(1124, pa->data.reg.reg == 0);
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
- break;
- case 'C':
- CError_ASSERT(1129, pa->data.reg.reg == 2);
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
- break;
- case 'L':
- CError_ASSERT(1134, pa->data.reg.reg == 1);
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
- break;
- case 'Z':
- CError_ASSERT(1139, pa->data.reg.reg == 0);
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
- break;
- case 'P':
- if (isdigit(format[1]))
- format += pcode_const_from_format(format + 1, &thing);
- else
- CError_FATAL(1149);
- case 'S':
- case 'T':
- case 's':
- if (pa->kind == PCOp_REGISTER && pa->arg == RegClass_SPR) {
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_SPR, -1, buf);
- } else {
- for (i = 0; i < 4; i++) {
- if (pa->data.reg.reg == spr_to_sysreg[i]) {
- CError_FATAL(1161);
- break;
- }
- }
-
- buf += expectandformatoperand(pa, PCOp_SYSREG, RegClass_SPR, -1, buf);
- }
- break;
-
- case 'V':
- do {
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_GPR, -1, buf);
- *(buf++) = ',';
- pa++;
- arg_index++;
- } while (arg_index < pcode->argCount && pa->kind == PCOp_REGISTER && pa->arg == RegClass_GPR);
- buf--;
- pa--;
- arg_index--;
- break;
-
- case 'Y':
- do {
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_CRFIELD, -1, buf);
- *(buf++) = ',';
- pa++;
- arg_index++;
- } while (arg_index < pcode->argCount && pa->kind == PCOp_REGISTER && pa->arg == RegClass_CRFIELD);
- buf--;
- pa--;
- arg_index--;
- break;
-
- case 'Q':
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_CRFIELD, -1, buf);
- *(buf++) = ',';
- pa++;
- arg_index++;
- case 'q':
- if (pa->kind == PCOp_IMMEDIATE && pa->data.imm.value >= 0 && pa->data.imm.value < 4 && (name = cc[pa->data.imm.value])[0]) {
- buf += sprintf(buf, "%s", name);
- } else {
- buf += sprintf(buf, "{OUT OF RANGE}");
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 0, -1, buf);
- }
- break;
- case 'a':
- case 'i':
- case 'u':
- case 'x':
- tmp = *format;
- if (tmp == 'a') {
- if (isdigit(format[1])) {
- format++;
- tmp = *format;
- } else {
- CError_FATAL(1227);
- }
- }
- if ((tmp2 = isdigit(format[1])))
- format += pcode_const_from_format(format + 1, &thing2);
- if (!tmp2)
- thing2 = -1;
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, tmp, thing2, buf);
- break;
-
- case 'N':
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 'u', 6, buf);
- break;
-
- case 'D':
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 'u', 10, buf);
- break;
-
- case 't':
- if (pa->kind == PCOp_IMMEDIATE && pa->data.imm.value > 0 && pa->data.imm.value < 31 && (name = to[pa->data.imm.value])[0]) {
- buf += sprintf(buf, "%s", name);
- break;
- }
-
- case 'B':
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 'x', 5, buf);
- break;
-
- case 'l':
- if (pa->kind == PCOp_IMMEDIATE) {
- buf += sprintf(buf, "*%s%" PRId32, (pa->data.imm.value >= 0) ? "+" : "", pa->data.imm.value);
- } else if (pa->kind == PCOp_LABELDIFF) {
- buf += expectandformatoperand(pa, PCOp_LABELDIFF, 0, -1, buf);
- } else if (pa->kind == PCOp_LABEL) {
- buf += expectandformatoperand(pa, PCOp_LABEL, 0, -1, buf);
- } else {
- buf += expectandformatoperand(pa, PCOp_MEMORY, 0, -1, buf);
- }
- break;
-
- case 'd':
- if (pa[1].kind == PCOp_MEMORY)
- buf += expectandformatoperand(pa + 1, PCOp_MEMORY, 0, -1, buf);
- else
- buf += expectandformatoperand(pa + 1, PCOp_IMMEDIATE, 0, -1, buf);
- CError_ASSERT(1283, format[1] == '(');
- format++;
- *(buf++) = *(format++);
- if (*format == '+')
- format++;
- CError_ASSERT(1291, format[0] == 'b');
- if (pa->kind == PCOp_REGISTER && pa->arg == RegClass_GPR && pa->data.reg.reg == 0) {
- if (pa->data.reg.effect & (EffectRead | EffectWrite)) {
- pclist_bad_operand = 1;
- buf += sprintf(buf, "!!!r");
- }
- buf += sprintf(buf, "0");
- } else {
- buf += expectandformatoperand(pa, PCOp_REGISTER, RegClass_GPR, -1, buf);
- }
- pa++;
- i++;
- break;
-
- case 'w':
- if (pa->kind == PCOp_LABELDIFF)
- buf += expectandformatoperand(pa, PCOp_LABELDIFF, 0, -1, buf);
- else
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 0, -1, buf);
- break;
-
- case 'm':
- case 'n':
- if (pa->kind == PCOp_MEMORY)
- buf += expectandformatoperand(pa, PCOp_MEMORY, 0, -1, buf);
- else if (pa->kind == PCOp_LABELDIFF)
- buf += expectandformatoperand(pa, PCOp_LABELDIFF, 0, -1, buf);
- else if ((pcode->flags & (fIsBranch | fIsCall)) && (pa->kind == PCOp_LABEL))
- buf += expectandformatoperand(pa, PCOp_LABEL, 0, -1, buf);
- else
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 0, -1, buf);
- break;
-
- case 'M':
- if (pa->kind == PCOp_MEMORY) {
- CError_ASSERT(1335, pa->arg == RefType_8 || pa->arg == RefType_B || pa->arg == RefType_C);
- buf += expectandformatoperand(pa, PCOp_MEMORY, 0, -1, buf);
- } else if (pa->kind == PCOp_LABELDIFF)
- buf += expectandformatoperand(pa, PCOp_LABELDIFF, 0, -1, buf);
- else
- buf += expectandformatoperand(pa, PCOp_IMMEDIATE, 0, -1, buf);
- break;
-
- case 'O':
- pa--;
- arg_index--;
- break;
-
- case 'p':
- buf += expectandformatoperand(pa, PCOp_PLACEHOLDEROPERAND, 0, -1, buf);
- break;
-
- default:
- CError_FATAL(1465);
- }
-
- while (format[1] && strchr("/<>|*", format[1])) {
- switch (*(++format)) {
- case '/':
- if (format[1] == '2')
- format++;
- break;
- case '<':
- case '*':
- case '|':
- case '>':
- if (format[1] == 'p')
- format++;
- else if (isdigit(format[1]))
- format += pcode_const_from_format(format + 1, &thing4);
- else
- CError_FATAL(1495);
- break;
- }
- }
-
- if ((c = *(++format)) == ']' || c == ')') {
- *(buf++) = c;
- format++;
- }
-
- pa++;
- arg_index++;
- }
-
- if (buf[-1] == ',')
- buf--;
-
- flagSetT = PCODE_FLAG_SET_T(pcode);
- flagSetF = PCODE_FLAG_SET_F(pcode);
- if (pcode->flags & fIsConst)
- buf += sprintf(buf, "; fIsConst");
- if (pcode->flags & fIsVolatile)
- buf += sprintf(buf, "; fIsVolatile");
- if (pcode->flags & fSideEffects)
- buf += sprintf(buf, "; fSideEffects");
- if (pcode->flags & fIsCSE)
- buf += sprintf(buf, "; fIsCSE");
- if (pcode->flags & fCommutative)
- buf += sprintf(buf, "; fCommutative");
-
- if (flagSetF & fIsPtrOp)
- buf += sprintf(buf, "; fIsPtrOp");
-
- if (flagSetT) {
- if (flagSetT & fLink)
- buf += sprintf(buf, "; fLink");
- if (flagSetT & fAbsolute)
- buf += sprintf(buf, "; fAbsolute");
- if (flagSetT & fBranchTaken)
- buf += sprintf(buf, "; fBranchTaken");
- if (flagSetT & fBranchNotTaken)
- buf += sprintf(buf, "; fBranchNotTaken");
- } else if (flagSetF) {
- if (flagSetF & fSetsCarry)
- buf += sprintf(buf, "; fSetsCarry");
- if (flagSetF & fOverflow)
- buf += sprintf(buf, "; fOverflow");
- }
-
- *buf = 0;
-}
-
-PCode *makecopyinstruction(PCodeArg *a, PCodeArg *b) {
- if (b->kind == PCOp_REGISTER) {
- switch (b->arg) {
- case RegClass_GPR:
- return makepcode(PC_MR, b->data.reg.reg, a->data.reg.reg);
- case RegClass_FPR:
- return makepcode(PC_FMR, b->data.reg.reg, a->data.reg.reg);
- case RegClass_VR:
- return makepcode(PC_VMR, b->data.reg.reg, a->data.reg.reg);
- case RegClass_CRFIELD:
- return makepcode(PC_MCRF, b->data.reg.reg, a->data.reg.reg);
- }
- }
-
- CError_FATAL(1622);
- return NULL;
-}
-
-int is_location_independent(PCode *pcode) {
- switch (pcode->op) {
- case PC_LI:
- case PC_LIS:
- case PC_VSPLTISB:
- case PC_VSPLTISH:
- case PC_VSPLTISW:
- return 1;
- case PC_ADDI:
- case PC_ADDIS:
- case PC_ORI:
- case PC_ORIS:
- return pcode->args[1].data.reg.reg == _FP_;
- case PC_LWZ:
- if (
- pcode->args[1].data.reg.reg == 1 &&
- pcode->args[2].kind == PCOp_IMMEDIATE &&
- pcode->args[2].data.imm.value == 0
- )
- return 1;
- }
-
- return 0;
-}
-
-int can_reuse_stored_value(PCode *a, PCode *b) {
- switch (b->op) {
- case PC_LWZ:
- case PC_LWZU:
- case PC_LWZX:
- case PC_LWZUX:
- switch (a->op) {
- case PC_STW:
- case PC_STWU:
- case PC_STWX:
- case PC_STWUX:
- return 1;
- }
- break;
-
- case PC_LFD:
- case PC_LFDU:
- case PC_LFDX:
- case PC_LFDUX:
- switch (a->op) {
- case PC_STFD:
- case PC_STFDU:
- case PC_STFDX:
- case PC_STFDUX:
- return 1;
- }
- break;
-
- case PC_LVX:
- if (a->op == PC_STVX)
- return 1;
- break;
- }
-
- return 0;
-}
-
-int nbytes_loaded_or_stored_by(PCode *pcode) {
- OpcodeInfo *oinfo = opcodeinfo + pcode->op;
- if (oinfo->flags & (fIsRead | fIsWrite)) {
- switch (pcode->op) {
- case PC_LBZ:
- case PC_LBZU:
- case PC_LBZX:
- case PC_LBZUX:
- case PC_STB:
- case PC_STBU:
- case PC_STBX:
- case PC_STBUX:
- return 1;
- case PC_LHZ:
- case PC_LHZU:
- case PC_LHZX:
- case PC_LHZUX:
- case PC_LHA:
- case PC_LHAU:
- case PC_LHAX:
- case PC_LHAUX:
- case PC_LHBRX:
- case PC_STH:
- case PC_STHU:
- case PC_STHX:
- case PC_STHUX:
- case PC_STHBRX:
- return 2;
- case PC_LWZ:
- case PC_LWZU:
- case PC_LWZX:
- case PC_LWZUX:
- case PC_LWBRX:
- case PC_STW:
- case PC_STWU:
- case PC_STWX:
- case PC_STWUX:
- case PC_STWBRX:
- case PC_LFS:
- case PC_LFSU:
- case PC_LFSX:
- case PC_LFSUX:
- case PC_STFS:
- case PC_STFSU:
- case PC_STFSX:
- case PC_STFSUX:
- case PC_LWARX:
- case PC_STFIWX:
- case PC_STWCX:
- case PC_ECIWX:
- case PC_ECOWX:
- case PC_MFROM:
- case PC_LSCBX:
- return 4;
- case PC_LMW:
- case PC_STMW:
- if (pcode->args[0].kind == PCOp_REGISTER && pcode->args[0].arg == RegClass_GPR)
- return (32 - pcode->args[0].data.reg.reg) * 4;
- else
- return 128;
- case PC_LFD:
- case PC_LFDU:
- case PC_LFDX:
- case PC_LFDUX:
- case PC_STFD:
- case PC_STFDU:
- case PC_STFDX:
- case PC_STFDUX:
- return 8;
- case PC_LSWI:
- case PC_STSWI:
- return pcode->args[2].data.imm.value; // not sure if imm is the right union type here
- case PC_LSWX:
- case PC_STSWX:
- return 128;
-
- // there's probably an ifdef here lmao
- case PC_LVEBX:
- case PC_STVEBX:
- return 1;
- case PC_LVEHX:
- case PC_STVEHX:
- return 2;
- case PC_LVEWX:
- case PC_STVEWX:
- return 4;
- case PC_LVSL:
- case PC_LVSR:
- case PC_LVX:
- case PC_LVXL:
- case PC_STVX:
- case PC_STVXL:
- return 16;
-
- default:
- CError_FATAL(2011);
- }
- }
-
- CError_FATAL(2014);
- return 0;
-}
-
-void change_num_operands(PCode *pcode, int newNum) {
- int i;
-
- CError_ASSERT(2026, ((pcode->argCount > 5) ? pcode->argCount : 5) >= newNum);
-
- for (i = pcode->argCount - 1; i >= newNum; i--)
- pcode->args[i].kind = PCOp_PLACEHOLDEROPERAND;
-
- pcode->argCount = newNum;
-}
-
-void change_opcode(PCode *pcode, short opcode) {
- pcode->flags = (pcode->flags & ~(opcodeinfo[pcode->op].flags & ~fIsPtrOp)) | opcodeinfo[opcode].flags;
- if ((pcode->flags & fIsMove) && (PCODE_FLAG_SET_F(pcode) & fRecordBit))
- pcode->flags &= ~fIsMove;
- pcode->op = opcode;
-}