diff options
Diffstat (limited to 'compiler_and_linker/unsorted/PCodeInfo.c')
-rw-r--r-- | compiler_and_linker/unsorted/PCodeInfo.c | 1354 |
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; -} |