diff options
Diffstat (limited to 'compiler_and_linker/unsorted/PCodeAssembly.c')
-rw-r--r-- | compiler_and_linker/unsorted/PCodeAssembly.c | 1613 |
1 files changed, 0 insertions, 1613 deletions
diff --git a/compiler_and_linker/unsorted/PCodeAssembly.c b/compiler_and_linker/unsorted/PCodeAssembly.c deleted file mode 100644 index 368f8c5..0000000 --- a/compiler_and_linker/unsorted/PCodeAssembly.c +++ /dev/null @@ -1,1613 +0,0 @@ -#include "compiler/PCodeAssembly.h" -#include "compiler/CError.h" -#include "compiler/CFunc.h" -#include "compiler/CMangler.h" -#include "compiler/CParser.h" -#include "compiler/CodeGen.h" -#include "compiler/ObjGenMachO.h" -#include "compiler/PCode.h" -#include "compiler/PCodeInfo.h" -#include "compiler/PCodeListing.h" -#include "compiler/PPCError.h" -#include "compiler/RegisterInfo.h" -#include "compiler/StackFrame.h" -#include "compiler/TOC.h" -#include "compiler/objects.h" - -static UInt32 codebase; - -static SInt32 pcode_update_mem_labeldiff_imm(PCode *instr, const PCodeArg *op, WeirdOperand *wop) { - SInt32 offset; - Object *object; - UInt8 arg; - - if (op->kind == PCOp_MEMORY) { - object = op->data.mem.obj; - offset = op->data.mem.offset; - switch (object->datatype) { - case DLOCAL: - switch ((UInt8) op->arg) { - case RefType_1: - offset += local_offset_16(object); - break; - case RefType_D: - offset = local_offset_lo(object, offset); - break; - case RefType_C: - offset = local_offset_ha(object, offset); - break; - default: - CError_FATAL(83); - } - break; - case DDATA: - case DFUNC: - case DVFUNC: - case DNONLAZYPTR: - switch ((UInt8) op->arg) { - case RefType_6: - wop->type = MW_RELOC_5_LO16; - break; - case RefType_2: - wop->type = MW_RELOC_3; - break; - case RefType_3: - wop->type = MW_RELOC_4; - break; - case RefType_8: - wop->type = MW_RELOC_7_HA16; - break; - case RefType_7: - wop->type = MW_RELOC_6_HI16; - break; - default: - CError_FATAL(135); - } - - wop->x2 = object; - CError_ASSERT(144, offset == 0); - break; - default: - CError_FATAL(164); - } - } else if (op->kind == PCOp_LABELDIFF) { - arg = op->arg; - - offset = op->data.labeldiff.labelA->block->codeOffset - op->data.labeldiff.labelB->block->codeOffset; - offset += op->data.labeldiff.offset; - if (arg == 1) - offset = -offset; - - if (offset > 0x7FFF) - PPCError_Error(PPCErrorStr109); - else if (offset < -0x8000) - PPCError_Error(PPCErrorStr109); - } else if (op->kind == PCOp_IMMEDIATE) { - offset = op->data.imm.value; - } else { - CError_FATAL(193); - } - - return offset; -} - -UInt32 assemblepcode(PCode *instr, UInt32 offset, WeirdOperand *wop) { - UInt32 bits; - - bits = opcodeinfo[instr->op].insn; - wop->type = -1; - wop->x6 = 0; - - switch (instr->op) { - case PC_BL: { - int flag = PCODE_FLAG_SET_T(instr) & fAbsolute; - if (instr->args[0].kind == PCOp_MEMORY) { - bits |= instr->args[0].data.mem.offset & 0x3FFFFFC; - wop->type = MW_RELOC_2_BR24; - wop->x2 = instr->args[0].data.mem.obj; - if (flag == 0) - wop->type = MW_RELOC_2_BR24; - else - CError_FATAL(246); - } else if (instr->args[0].kind == PCOp_IMMEDIATE) { - bits |= instr->args[0].data.imm.value & 0x3FFFFFC; - if (flag) - bits |= 2; - } else { - bits |= (instr->args[0].data.label.label->block->codeOffset - offset) & 0x3FFFFFC; - if (flag) - CError_FATAL(261); - } - break; - } - - case PC_B: { - int flag = PCODE_FLAG_SET_T(instr) & fAbsolute; - if (instr->args[0].kind == PCOp_MEMORY) { - bits |= instr->args[0].data.mem.offset & 0x3FFFFFC; - wop->x2 = instr->args[0].data.mem.obj; - if (flag == 0) - wop->type = MW_RELOC_2_BR24; - else - CError_FATAL(288); - } else if (instr->args[0].kind == PCOp_IMMEDIATE) { - bits |= instr->args[0].data.imm.value & 0x3FFFFFC; - if (flag) - bits |= 2; - } else { - bits |= (instr->args[0].data.label.label->block->codeOffset - offset) & 0x3FFFFFC; - if (flag) - CError_FATAL(302); - } - if (PCODE_FLAG_SET_T(instr) & fLink) - bits |= 1; - break; - } - - case PC_BDNZ: - case PC_BDZ: { - int flag = PCODE_FLAG_SET_T(instr) & fAbsolute; - if (instr->args[0].kind == PCOp_MEMORY) { - bits |= instr->args[0].data.mem.offset & 0xFFFC; - wop->x2 = instr->args[0].data.mem.obj; - if (flag == 0) - wop->type = MW_RELOC_8; - else - CError_FATAL(333); - } else { - SInt32 value; - if (instr->args[0].kind == PCOp_IMMEDIATE) - value = instr->args[0].data.imm.value; - else - value = instr->args[0].data.label.label->block->codeOffset - offset; - - bits |= value & 0xFFFF; - if (value < 0) { - if (PCODE_FLAG_SET_T(instr) & fBranchNotTaken) - bits |= 0x200000u; - } else { - if (PCODE_FLAG_SET_T(instr) & fBranchTaken) - bits |= 0x200000u; - } - } - if (PCODE_FLAG_SET_T(instr) & fLink) - bits |= 1; - break; - } - - case PC_BC: { - int flag = PCODE_FLAG_SET_T(instr) & fAbsolute; - bits |= (instr->args[0].data.imm.value & 31) << 21; - bits |= ((instr->args[1].data.reg.reg * 4 + instr->args[2].data.imm.value) & 31) << 16; - - if (instr->args[3].kind == PCOp_MEMORY) { - bits |= instr->args[3].data.mem.offset & 0xFFFC; - wop->x2 = instr->args[3].data.mem.obj; - if (flag == 0) - wop->type = MW_RELOC_8; - else - CError_FATAL(387); - } else { - SInt32 value; - if (instr->args[3].kind == PCOp_IMMEDIATE) - value = instr->args[3].data.imm.value; - else - value = instr->args[3].data.label.label->block->codeOffset - offset; - - bits |= value & 0xFFFF; - if (value < 0) { - if (PCODE_FLAG_SET_T(instr) & fBranchNotTaken) - bits |= 0x200000u; - } else { - if (PCODE_FLAG_SET_T(instr) & fBranchTaken) - bits |= 0x200000u; - } - } - if (PCODE_FLAG_SET_T(instr) & fLink) - bits |= 1; - break; - } - - case PC_BT: - case PC_BF: - case PC_BDNZT: - case PC_BDNZF: - case PC_BDZT: - case PC_BDZF: { - int flag = PCODE_FLAG_SET_T(instr) & fAbsolute; - bits |= ((instr->args[0].data.reg.reg * 4 + instr->args[1].data.imm.value) & 31) << 16; - - if (instr->args[2].kind == PCOp_MEMORY) { - bits |= instr->args[2].data.mem.offset & 0xFFFC; - wop->x2 = instr->args[2].data.mem.obj; - if (flag == 0) - wop->type = MW_RELOC_8; - else - CError_FATAL(446); - } else { - SInt32 value; - if (instr->args[2].kind == PCOp_IMMEDIATE) { - value = instr->args[2].data.imm.value; - if (flag) - bits |= 2; - } else { - value = instr->args[2].data.label.label->block->codeOffset - offset; - CError_ASSERT(458, !flag); - } - - bits |= value & 0xFFFF; - - if (value < 0) { - if (PCODE_FLAG_SET_T(instr) & fBranchNotTaken) - bits |= 0x200000u; - } else { - if (PCODE_FLAG_SET_T(instr) & fBranchTaken) - bits |= 0x200000u; - } - } - - if (PCODE_FLAG_SET_T(instr) & fLink) - bits |= 1; - break; - } - - case PC_BTLR: - case PC_BTCTR: - case PC_BFLR: - case PC_BFCTR: - bits |= ((instr->args[0].data.reg.reg * 4 + instr->args[1].data.imm.value) & 31) << 16; - if (PCODE_FLAG_SET_T(instr) & fLink) - bits |= 1; - if (PCODE_FLAG_SET_T(instr) & fBranchTaken) - bits |= 0x200000u; - break; - - case PC_BCLR: - case PC_BCCTR: - bits |= instr->args[0].data.imm.value << 21; - bits |= ((instr->args[1].data.reg.reg * 4 + instr->args[2].data.imm.value) & 31) << 16; - case PC_BLR: - case PC_BCTR: - case PC_BCTRL: - case PC_BLRL: - if (PCODE_FLAG_SET_T(instr) & fLink) - bits |= 1; - if (PCODE_FLAG_SET_T(instr) & fBranchTaken) - bits |= 0x200000u; - break; - - case PC_CRAND: - case PC_CRANDC: - case PC_CREQV: - case PC_CRNAND: - case PC_CRNOR: - case PC_CROR: - case PC_CRORC: - case PC_CRXOR: - bits |= ((instr->args[0].data.reg.reg * 4 + instr->args[1].data.imm.value) & 31) << 21; - bits |= ((instr->args[2].data.reg.reg * 4 + instr->args[3].data.imm.value) & 31) << 16; - bits |= ((instr->args[4].data.reg.reg * 4 + instr->args[5].data.imm.value) & 31) << 11; - break; - - case PC_MCRF: - bits |= instr->args[0].data.reg.reg << 23; - bits |= instr->args[1].data.reg.reg << 18; - break; - - case PC_LBZ: - case PC_LBZU: - case PC_LHZ: - case PC_LHZU: - case PC_LHA: - case PC_LHAU: - case PC_LWZ: - case PC_LWZU: - case PC_LMW: - case PC_STB: - case PC_STBU: - case PC_STH: - case PC_STHU: - case PC_STW: - case PC_STWU: - case PC_STMW: - case PC_LFS: - case PC_LFSU: - case PC_LFD: - case PC_LFDU: - case PC_STFS: - case PC_STFSU: - case PC_STFD: - case PC_STFDU: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= pcode_update_mem_labeldiff_imm(instr, &instr->args[2], wop) & 0xFFFF; - break; - - case PC_LBZX: - case PC_LBZUX: - case PC_LHZX: - case PC_LHZUX: - case PC_LHAX: - case PC_LHAUX: - case PC_LHBRX: - case PC_LWZX: - case PC_LWZUX: - case PC_LWBRX: - case PC_STBX: - case PC_STBUX: - case PC_STHX: - case PC_STHUX: - case PC_STHBRX: - case PC_STWX: - case PC_STWUX: - case PC_STWBRX: - case PC_LFSX: - case PC_LFSUX: - case PC_LFDX: - case PC_LFDUX: - case PC_STFSX: - case PC_STFSUX: - case PC_STFDX: - case PC_STFDUX: - case PC_LWARX: - case PC_LSWX: - case PC_STFIWX: - case PC_STSWX: - case PC_STWCX: - case PC_ECIWX: - case PC_ECOWX: - case PC_DCREAD: - case PC_TLBSX: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_DCBF: - case PC_DCBST: - case PC_DCBT: - case PC_DCBTST: - case PC_DCBZ: - case PC_DCBI: - case PC_ICBI: - case PC_DCCCI: - case PC_ICBT: - case PC_ICCCI: - case PC_ICREAD: - case PC_DCBA: - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 11; - break; - - case PC_ADD: - case PC_ADDC: - case PC_ADDE: - case PC_DIVW: - case PC_DIVWU: - case PC_MULHW: - case PC_MULHWU: - case PC_MULLW: - case PC_SUBF: - case PC_SUBFC: - case PC_SUBFE: - bits |= instr->args[2].data.reg.reg << 11; - case PC_ADDME: - case PC_ADDZE: - case PC_NEG: - case PC_SUBFME: - case PC_SUBFZE: - case PC_MFROM: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - if (PCODE_FLAG_SET_F(instr) & fOverflow) - bits |= 0x400; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_ADDI: - case PC_ADDIC: - case PC_ADDICR: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= pcode_update_mem_labeldiff_imm(instr, &instr->args[2], wop) & 0xFFFF; - break; - - case PC_ADDIS: - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[0].data.reg.reg << 21; - bits |= pcode_update_mem_labeldiff_imm(instr, &instr->args[2], wop) & 0xFFFF; - break; - - case PC_MULLI: - case PC_SUBFIC: - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[2].data.imm.value & 0xFFFF; - break; - - case PC_LI: - case PC_LIS: - bits |= instr->args[0].data.reg.reg << 21; - bits |= pcode_update_mem_labeldiff_imm(instr, &instr->args[1], wop) & 0xFFFF; - break; - - case PC_ANDI: - case PC_ANDIS: - case PC_ORI: - case PC_ORIS: - case PC_XORI: - case PC_XORIS: - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 21; - bits |= pcode_update_mem_labeldiff_imm(instr, &instr->args[2], wop) & 0xFFFF; - break; - - case PC_AND: - case PC_OR: - case PC_XOR: - case PC_NAND: - case PC_NOR: - case PC_EQV: - case PC_ANDC: - case PC_ORC: - case PC_SLW: - case PC_SRW: - case PC_SRAW: - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 21; - bits |= instr->args[2].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_EXTSH: - case PC_EXTSB: - case PC_CNTLZW: - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 21; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_MR: - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_NOT: - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_SRAWI: - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 21; - bits |= (instr->args[2].data.imm.value & 31) << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_RLWINM: - case PC_RLWIMI: - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 21; - bits |= (instr->args[2].data.imm.value & 31) << 11; - bits |= (instr->args[3].data.imm.value & 31) << 6; - bits |= (instr->args[4].data.imm.value & 31) << 1; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_RLWNM: - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 21; - bits |= instr->args[2].data.reg.reg << 11; - bits |= (instr->args[3].data.imm.value & 31) << 6; - bits |= (instr->args[4].data.imm.value & 31) << 1; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_CMP: - case PC_CMPL: - bits |= instr->args[0].data.reg.reg << 23; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - break; - - case PC_CMPI: - case PC_CMPLI: - bits |= instr->args[0].data.reg.reg << 23; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.imm.value & 0xFFFF; - break; - - case PC_MTXER: - case PC_MTCTR: - case PC_MTLR: - case PC_MTMSR: - case PC_MFMSR: - case PC_MFXER: - case PC_MFCTR: - case PC_MFLR: - case PC_MFCR: - bits |= instr->args[0].data.reg.reg << 21; - break; - - case PC_MFFS: - bits |= instr->args[0].data.reg.reg << 21; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_MTCRF: - bits |= instr->args[0].data.imm.value << 12; - bits |= instr->args[1].data.reg.reg << 21; - break; - - case PC_MTFSF: - bits |= (instr->args[0].data.imm.value & 0xFF) << 17; - bits |= instr->args[1].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_FMR: - case PC_FABS: - case PC_FNEG: - case PC_FNABS: - case PC_FRES: - case PC_FRSQRTE: - case PC_FRSP: - case PC_FCTIW: - case PC_FCTIWZ: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_FADD: - case PC_FADDS: - case PC_FSUB: - case PC_FSUBS: - case PC_FDIV: - case PC_FDIVS: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_FMADD: - case PC_FMADDS: - case PC_FMSUB: - case PC_FMSUBS: - case PC_FNMADD: - case PC_FNMADDS: - case PC_FNMSUB: - case PC_FNMSUBS: - case PC_FSEL: - bits |= instr->args[3].data.reg.reg << 11; - case PC_FMUL: - case PC_FMULS: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 6; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_FCMPU: - case PC_FCMPO: - bits |= instr->args[0].data.reg.reg << 23; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - break; - - case PC_MTSPR: - if (instr->args[0].kind == PCOp_REGISTER) { - CError_ASSERT(1027, instr->args[0].arg == RegClass_SPR); - CError_ASSERT(1028, instr->args[0].data.reg.reg < 4); - bits |= ((spr_to_sysreg[instr->args[0].data.reg.reg] & 0x1F) << 16) + - ((spr_to_sysreg[instr->args[0].data.reg.reg] & 0x3E0) << 6); - } else if (instr->args[0].kind == PCOp_SYSREG && instr->args[0].arg == 0) { - bits |= ((instr->args[0].data.reg.reg & 0x1F) << 16) + - ((instr->args[0].data.reg.reg & 0x3E0) << 6); - } else { - CError_FATAL(1033); - } - - bits |= instr->args[1].data.reg.reg << 21; - break; - - case PC_MTDCR: - if (instr->args[0].kind == PCOp_IMMEDIATE) { - bits |= ((instr->args[0].data.imm.value & 0x1F) << 16) + - ((instr->args[0].data.imm.value & 0x3E0) << 6); - } else { - CError_FATAL(1042); - } - - bits |= instr->args[1].data.reg.reg << 21; - break; - - case PC_MFSPR: - bits |= instr->args[0].data.reg.reg << 21; - - if (instr->args[1].kind == PCOp_REGISTER && instr->args[1].arg == RegClass_SPR) { - CError_ASSERT(1055, instr->args[1].data.reg.reg < 4); - bits |= ((spr_to_sysreg[instr->args[1].data.reg.reg] & 0x1F) << 16) + - ((spr_to_sysreg[instr->args[1].data.reg.reg] & 0x3E0) << 6); - } else if (instr->args[1].kind == PCOp_SYSREG && instr->args[1].arg == 0) { - bits |= ((instr->args[1].data.reg.reg & 0x1F) << 16) + - ((instr->args[1].data.reg.reg & 0x3E0) << 6); - } else { - CError_FATAL(1060); - } - break; - - case PC_MFDCR: - bits |= instr->args[0].data.reg.reg << 21; - - if (instr->args[1].kind == PCOp_IMMEDIATE) { - bits |= ((instr->args[1].data.imm.value & 0x1F) << 16) + - ((instr->args[1].data.imm.value & 0x3E0) << 6); - } else { - CError_FATAL(1069); - } - break; - - case PC_LSWI: - case PC_STSWI: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= (instr->args[2].data.imm.value & 31) << 11; - break; - - case PC_MCRFS: - bits |= (instr->args[1].data.imm.value & 7) << 18; - case PC_MCRXR: - bits |= instr->args[0].data.reg.reg << 23; - break; - - case PC_MFTB: - bits |= instr->args[0].data.reg.reg << 21; - if (instr->args[1].kind == PCOp_SYSREG && instr->args[1].arg == 0) { - if (instr->args[1].data.reg.reg == 284) - bits |= 0xC4000u; - else if (instr->args[1].data.reg.reg == 285) - bits |= 0xD4000u; - else - CError_FATAL(1100); - } else { - CError_FATAL(1103); - } - break; - - case PC_MTSR: - bits |= instr->args[1].data.reg.reg << 21; - bits |= (instr->args[0].data.imm.value & 15) << 16; - break; - - case PC_MFSR: - bits |= instr->args[0].data.reg.reg << 21; - bits |= (instr->args[1].data.imm.value & 15) << 16; - break; - - case PC_MFSRIN: - case PC_MTSRIN: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 11; - break; - - case PC_MTFSB0: - case PC_MTFSB1: - bits |= (instr->args[0].data.imm.value & 31) << 21; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_MTFSFI: - bits |= instr->args[0].data.reg.reg << 23; - bits |= (instr->args[1].data.imm.value & 15) << 12; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_FSQRT: - case PC_FSQRTS: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_TLBIE: - case PC_TLBLD: - case PC_TLBLI: - bits |= instr->args[0].data.reg.reg << 11; - break; - - case PC_TW: - bits |= (instr->args[0].data.imm.value & 31) << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - break; - - case PC_TWI: - bits |= (instr->args[0].data.imm.value & 31) << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.imm.value & 0xFFFF; - break; - - case PC_OPWORD: - CError_ASSERT(1176, instr->args[0].kind != PCOp_MEMORY); - bits = pcode_update_mem_labeldiff_imm(instr, &instr->args[0], wop); - break; - - case PC_MASKG: - case PC_MASKIR: - bits |= instr->args[1].data.reg.reg << 21; - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_LSCBX: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_DIV: - case PC_DIVS: - case PC_DOZ: - case PC_MUL: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fOverflow) - bits |= 0x400; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_NABS: - case PC_ABS: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - if (PCODE_FLAG_SET_F(instr) & fOverflow) - bits |= 0x400; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_CLCS: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_DOZI: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.imm.value & 0xFFFF; - break; - - case PC_RLMI: - bits |= instr->args[1].data.reg.reg << 21; - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - bits |= (instr->args[3].data.imm.value & 31) << 6; - bits |= (instr->args[4].data.imm.value & 31) << 1; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_SLE: - case PC_SLEQ: - case PC_SLLQ: - case PC_SLQ: - case PC_SRAQ: - case PC_SRE: - case PC_SREA: - case PC_SREQ: - case PC_SRLQ: - case PC_SRQ: - case PC_RRIB: - bits |= instr->args[1].data.reg.reg << 21; - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_SLIQ: - case PC_SLLIQ: - case PC_SRAIQ: - case PC_SRIQ: - case PC_SRLIQ: - bits |= instr->args[1].data.reg.reg << 21; - bits |= instr->args[0].data.reg.reg << 16; - bits |= (instr->args[2].data.imm.value & 31) << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 1; - break; - - case PC_TLBRE: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= (instr->args[2].data.imm.value & 1) << 11; - break; - - case PC_TLBWE: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= (instr->args[2].data.imm.value & 1) << 11; - break; - - case PC_WRTEE: - bits |= instr->args[0].data.reg.reg << 21; - break; - - case PC_WRTEEI: - bits |= instr->args[0].data.imm.value << 15; - break; - - case PC_DSTT: - case PC_DSTSTT: - bits |= 0x2000000u; - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 11; - bits |= (instr->args[2].data.imm.value & 3) << 21; - break; - - case PC_DST: - case PC_DSTST: - bits |= (instr->args[3].data.imm.value & 1) << 25; - bits |= instr->args[0].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 11; - bits |= (instr->args[2].data.imm.value & 3) << 21; - break; - - case PC_DSSALL: - bits |= 0x2000000u; - break; - - case PC_DSS: - bits |= (instr->args[1].data.imm.value & 1) << 25; - bits |= (instr->args[0].data.imm.value & 3) << 21; - break; - - case PC_LVEBX: - case PC_LVEHX: - case PC_LVEWX: - case PC_LVSL: - case PC_LVSR: - case PC_LVX: - case PC_LVXL: - case PC_STVEBX: - case PC_STVEHX: - case PC_STVEWX: - case PC_STVX: - case PC_STVXL: - case PC_VADDCUW: - case PC_VADDFP: - case PC_VADDSBS: - case PC_VADDSHS: - case PC_VADDSWS: - case PC_VADDUBM: - case PC_VADDUBS: - case PC_VADDUHM: - case PC_VADDUHS: - case PC_VADDUWM: - case PC_VADDUWS: - case PC_VAND: - case PC_VANDC: - case PC_VAVGSB: - case PC_VAVGSH: - case PC_VAVGSW: - case PC_VAVGUB: - case PC_VAVGUH: - case PC_VAVGUW: - case PC_VMAXFP: - case PC_VMAXSB: - case PC_VMAXSH: - case PC_VMAXSW: - case PC_VMAXUB: - case PC_VMAXUH: - case PC_VMAXUW: - case PC_VMINFP: - case PC_VMINSB: - case PC_VMINSH: - case PC_VMINSW: - case PC_VMINUB: - case PC_VMINUH: - case PC_VMINUW: - case PC_VMRGHB: - case PC_VMRGHH: - case PC_VMRGHW: - case PC_VMRGLB: - case PC_VMRGLH: - case PC_VMRGLW: - case PC_VMULESB: - case PC_VMULESH: - case PC_VMULEUB: - case PC_VMULEUH: - case PC_VMULOSB: - case PC_VMULOSH: - case PC_VMULOUB: - case PC_VMULOUH: - case PC_VNOR: - case PC_VOR: - case PC_VPKPX: - case PC_VPKSHSS: - case PC_VPKSHUS: - case PC_VPKSWSS: - case PC_VPKSWUS: - case PC_VPKUHUM: - case PC_VPKUHUS: - case PC_VPKUWUM: - case PC_VPKUWUS: - case PC_VRLB: - case PC_VRLH: - case PC_VRLW: - case PC_VSL: - case PC_VSLB: - case PC_VSLH: - case PC_VSLO: - case PC_VSLW: - case PC_VSR: - case PC_VSRAB: - case PC_VSRAH: - case PC_VSRAW: - case PC_VSRB: - case PC_VSRH: - case PC_VSRO: - case PC_VSRW: - case PC_VSUBCUW: - case PC_VSUBFP: - case PC_VSUBSBS: - case PC_VSUBSHS: - case PC_VSUBSWS: - case PC_VSUBUBM: - case PC_VSUBUBS: - case PC_VSUBUHM: - case PC_VSUBUHS: - case PC_VSUBUWM: - case PC_VSUBUWS: - case PC_VSUMSWS: - case PC_VSUM2SWS: - case PC_VSUM4SBS: - case PC_VSUM4SHS: - case PC_VSUM4UBS: - case PC_VXOR: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - break; - - case PC_VCFSX: - case PC_VCFUX: - case PC_VCTSXS: - case PC_VCTUXS: - case PC_VSPLTB: - case PC_VSPLTH: - case PC_VSPLTW: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 11; - bits |= (instr->args[2].data.imm.value & 31) << 16; - break; - - case PC_VEXPTEFP: - case PC_VLOGEFP: - case PC_VREFP: - case PC_VRFIM: - case PC_VRFIN: - case PC_VRFIP: - case PC_VRFIZ: - case PC_VRSQRTEFP: - case PC_VUPKHPX: - case PC_VUPKHSB: - case PC_VUPKHSH: - case PC_VUPKLPX: - case PC_VUPKLSB: - case PC_VUPKLSH: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 11; - break; - - case PC_VCMPBFP: - case PC_VCMPEQFP: - case PC_VCMPEQUB: - case PC_VCMPEQUH: - case PC_VCMPEQUW: - case PC_VCMPGEFP: - case PC_VCMPGTFP: - case PC_VCMPGTSB: - case PC_VCMPGTSH: - case PC_VCMPGTSW: - case PC_VCMPGTUB: - case PC_VCMPGTUH: - case PC_VCMPGTUW: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - if (PCODE_FLAG_SET_F(instr) & fRecordBit) - bits |= 0x400; - break; - - case PC_VSPLTISB: - case PC_VSPLTISH: - case PC_VSPLTISW: - bits |= instr->args[0].data.reg.reg << 21; - bits |= (instr->args[1].data.imm.value & 31) << 16; - break; - - case PC_VMHADDSHS: - case PC_VMHRADDSHS: - case PC_VMLADDUHM: - case PC_VMSUMMBM: - case PC_VMSUMSHM: - case PC_VMSUMSHS: - case PC_VMSUMUBM: - case PC_VMSUMUHM: - case PC_VMSUMUHS: - case PC_VPERM: - case PC_VSEL: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - bits |= instr->args[3].data.reg.reg << 6; - break; - - case PC_VMADDFP: - case PC_VNMSUBFP: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 6; - bits |= instr->args[3].data.reg.reg << 11; - break; - - case PC_VSLDOI: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[2].data.reg.reg << 11; - bits |= (instr->args[3].data.imm.value & 15) << 6; - break; - - case PC_VMR: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 11; - break; - - case PC_VMRP: - bits |= instr->args[0].data.reg.reg << 21; - bits |= instr->args[1].data.reg.reg << 16; - bits |= instr->args[1].data.reg.reg << 11; - break; - - case PC_MFVSCR: - bits |= instr->args[0].data.reg.reg << 21; - break; - - case PC_MTVSCR: - bits |= instr->args[0].data.reg.reg << 11; - break; - - case PC_EIEIO: - case PC_ISYNC: - case PC_SYNC: - case PC_RFI: - case PC_NOP: - case PC_SC: - case PC_TLBIA: - case PC_TLBSYNC: - case PC_TRAP: - case PC_DSA: - case PC_ESA: - case PC_RFCI: - break; - - default: - CError_FATAL(2203); - } - - return CTool_EndianConvertWord32(bits); -} - -static PCode *targetinstruction(PCodeLabel *label) { - PCodeBlock *block = label->block; - while (block->pcodeCount == 0) - block = block->nextBlock; - return block->firstPCode; -} - -static void invertybit(PCode *instr, SInt32 value) { - if (instr->op == PC_BC) { - if (instr->args[0].data.imm.value & 1) { - if (value < 0) - instr->flags |= fBranchNotTaken; - else - instr->flags |= fBranchTaken; - } - } else if (instr->op == PC_BCCTR || instr->op == PC_BCLR) { - if (instr->args[0].data.imm.value & 1) - instr->flags |= fBranchTaken; - } - - if (PCODE_FLAG_SET_T(instr) & fBranchTaken) - instr->flags = (instr->flags & ~fBranchTaken) | fBranchNotTaken; - else if (PCODE_FLAG_SET_T(instr) & fBranchNotTaken) - instr->flags = (instr->flags & ~fBranchNotTaken) | fBranchTaken; - else if (value < 0) - instr->flags = (instr->flags & ~fBranchTaken) | fBranchNotTaken; - else - instr->flags = (instr->flags & ~fBranchNotTaken) | fBranchTaken; -} - -static void insertlongbranches(SInt32 mask) { - PCodeBlock *block; - PCodeLabel *label; - SInt32 i; - - i = 0; - for (block = pcbasicblocks; block; block = block->nextBlock) { - block->codeOffset = i; - if (block->pcodeCount) { - i += block->pcodeCount * 4; - if (block->pcodeCount && (block->lastPCode->flags & fIsBranch)) - i += 4; - } - } - - for (block = pcbasicblocks; block; block = block->nextBlock) { - if (block->pcodeCount && (block->lastPCode->flags & fIsBranch)) { - switch (block->lastPCode->op) { - case PC_BT: - case PC_BF: - i = block->codeOffset + ((block->pcodeCount - 1) * 4); - if (block->lastPCode->args[2].kind == PCOp_LABEL) { - label = block->lastPCode->args[2].data.label.label; - i = label->block->codeOffset - i; - if (i != ((SInt16) (i & mask))) { - block->lastPCode->op = (block->lastPCode->op == PC_BT) ? PC_BF : PC_BT; - block->lastPCode->args[2].data.label.label = block->nextBlock->labels; - invertybit(block->lastPCode, i); - appendpcode(block, makepcode(PC_B, label)); - } - } - break; - - case PC_BC: - i = block->codeOffset + ((block->pcodeCount - 1) * 4); - if (block->lastPCode->args[3].kind == PCOp_LABEL) { - label = block->lastPCode->args[3].data.label.label; - i = label->block->codeOffset - i; - invertybit(block->lastPCode, i); - if (i != ((SInt16) (i & mask))) { - switch (block->lastPCode->args[0].data.imm.value & 30) { - case 0: - case 2: - case 8: - case 10: - block->lastPCode->args[0].data.imm.value ^= 11; - block->lastPCode->args[3].data.label.label = block->nextBlock->labels; - break; - case 16: - case 18: - block->lastPCode->args[0].data.imm.value ^= 3; - block->lastPCode->args[3].data.label.label = block->nextBlock->labels; - break; - case 4: - case 12: - block->lastPCode->args[0].data.imm.value ^= 9; - block->lastPCode->args[3].data.label.label = block->nextBlock->labels; - break; - case 20: - deletepcode(block->lastPCode); - break; - default: - CError_FATAL(2368); - } - - appendpcode(block, makepcode(PC_B, label)); - } - } - break; - - case PC_BDNZ: - case PC_BDZ: - i = block->codeOffset + ((block->pcodeCount - 1) * 4); - if (block->lastPCode->args[0].kind == PCOp_LABEL) { - label = block->lastPCode->args[0].data.label.label; - i = label->block->codeOffset - i; - if (i != ((SInt16) (i & mask))) { - switch (block->lastPCode->op) { - case PC_BDZ: - block->lastPCode->op = PC_BDNZ; - break; - case PC_BDNZ: - block->lastPCode->op = PC_BDZ; - break; - default: - CError_FATAL(2389); - } - - block->lastPCode->args[0].data.label.label = block->nextBlock->labels; - invertybit(block->lastPCode, i); - appendpcode(block, makepcode(PC_B, label)); - } - } - break; - - case PC_BDNZT: - case PC_BDNZF: - case PC_BDZT: - case PC_BDZF: - i = block->codeOffset + ((block->pcodeCount - 1) * 4); - if (block->lastPCode->args[2].kind == PCOp_LABEL) { - label = block->lastPCode->args[2].data.label.label; - i = label->block->codeOffset - i; - if (i != ((SInt16) (i & mask))) { - switch (block->lastPCode->op) { - case PC_BDNZT: - block->lastPCode->op = PC_BDZF; - break; - case PC_BDNZF: - block->lastPCode->op = PC_BDZT; - break; - case PC_BDZT: - block->lastPCode->op = PC_BDNZF; - break; - case PC_BDZF: - block->lastPCode->op = PC_BDNZT; - break; - default: - CError_FATAL(2420); - } - - block->lastPCode->args[2].data.label.label = block->nextBlock->labels; - invertybit(block->lastPCode, i); - appendpcode(block, makepcode(PC_B, label)); - } - } - break; - - } - } - } -} - -SInt32 optimizefinalbranches(SInt32 codesize) { - PCodeBlock *block; - PCode *instr; - SInt32 offset; - int changed; - int deleted; - PCodeLabel *label; - PCode *target; - - do { - changed = deleted = 0; - - for (block = pcbasicblocks; block; block = block->nextBlock) { - if (block->pcodeCount == 0) - continue; - - instr = block->lastPCode; - if (!(instr->flags & fIsBranch)) - continue; - - offset = block->codeOffset + (block->pcodeCount - 1) * 4; - - if (instr->op == PC_B && instr->args[0].kind == PCOp_LABEL) { - label = instr->args[0].data.label.label; - target = targetinstruction(label); - - if (label->block->codeOffset == (offset + 4)) { - deletepcode(instr); - changed = deleted = 1; - } else if (target->op == PC_B) { - if (target->args[0].kind == PCOp_LABEL && target->args[0].data.label.label != instr->args[0].data.label.label) { - instr->args[0].data.label.label = target->args[0].data.label.label; - changed = 1; - } - } else if (target->op == PC_BLR) { - instr->op = PC_BLR; - changed = 1; - } - continue; - } - - if ((instr->op == PC_BT || instr->op == PC_BF) && instr->args[2].kind == PCOp_LABEL) { - PCodeBlock *block2 = instr->block; - label = instr->args[2].data.label.label; - target = targetinstruction(label); - - if (label->block->codeOffset == (offset + 4)) { - deletepcode(instr); - changed = deleted = 1; - } else if (target->op == PC_B) { - if (target->args[0].kind == PCOp_LABEL && target->args[0].data.label.label != instr->args[2].data.label.label) { - instr->args[2].data.label.label = target->args[0].data.label.label; - changed = 1; - } - } else if (copts.opt_bcc_lr_ctr) { - if (target->op == PC_BLR) { - if (instr->op == PC_BT) - instr->op = PC_BTLR; - else - instr->op = PC_BFLR; - instr->argCount = 2; - changed = 1; - } else if (target->op == PC_BCTR) { - if (instr->op == PC_BT) - instr->op = PC_BTCTR; - else - instr->op = PC_BFCTR; - instr->argCount = 2; - changed = 1; - } else if ( - block2->nextBlock && - block2->nextBlock->firstPCode && - block2->nextBlock->firstPCode->op == PC_BLR && - label->block->codeOffset == (offset + 8) - ) { - if ( - block2->nextBlock->predecessors && - block2->nextBlock->predecessors->block == block2 && - !block2->nextBlock->predecessors->nextLink - ) { - if (instr->op == PC_BT) - instr->op = PC_BFLR; - else - instr->op = PC_BTLR; - change_num_operands(instr, 2); - deletepcode(block2->nextBlock->firstPCode); - changed = deleted = 1; - } - } else if ( - block2->nextBlock && - block2->nextBlock->firstPCode && - block2->nextBlock->firstPCode->op == PC_BCTR && - label->block->codeOffset == (offset + 8) - ) { - if ( - block2->nextBlock->predecessors && - block2->nextBlock->predecessors->block == block2 && - !block2->nextBlock->predecessors->nextLink - ) { - if (instr->op == PC_BT) - instr->op = PC_BFCTR; - else - instr->op = PC_BTCTR; - change_num_operands(instr, 2); - deletepcode(block2->nextBlock->firstPCode); - changed = deleted = 1; - } - } - } - continue; - } - - if ( - instr->op == PC_BC && - instr->args[3].kind == PCOp_LABEL && - !(PCODE_FLAG_SET_T(instr) & (fSideEffects | fLink)) - ) - { - PCodeBlock *block2 = instr->block; - label = instr->args[3].data.label.label; - target = targetinstruction(label); - - if (label->block->codeOffset == (offset + 4)) { - deletepcode(instr); - changed = deleted = 1; - } else if (target->op == PC_B) { - if (target->args[0].kind == PCOp_LABEL && target->args[0].data.label.label != instr->args[3].data.label.label) { - instr->args[3].data.label.label = target->args[0].data.label.label; - changed = 1; - } - } else if (copts.opt_bcc_lr_ctr) { - if (target->op == PC_BLR) { - instr->op = PC_BCLR; - instr->argCount = 3; - changed = 1; - } else if (target->op == PC_BCTR) { - instr->op = PC_BCCTR; - instr->argCount = 3; - changed = 1; - } else if ( - block2->nextBlock && - block2->nextBlock->firstPCode && - block2->nextBlock->firstPCode->op == PC_BLR && - label->block->codeOffset == (offset + 8) - ) { - SInt32 val = instr->args[0].data.imm.value & 30; - if ( - block2->nextBlock->predecessors && - block2->nextBlock->predecessors->block == block2 && - !block2->nextBlock->predecessors->nextLink - ) { - if ((val & 30) == 4) - instr->args[0].data.imm.value = val | 12; - else if ((val & 30) == 12) - instr->args[0].data.imm.value = val & 23; - instr->op = PC_BCLR; - instr->argCount = 3; - deletepcode(block2->nextBlock->firstPCode); - changed = deleted = 1; - } - } else if ( - block2->nextBlock && - block2->nextBlock->firstPCode && - block2->nextBlock->firstPCode->op == PC_BCTR && - label->block->codeOffset == (offset + 8) - ) { - SInt32 val = instr->args[0].data.imm.value & 30; - if ( - block2->nextBlock->predecessors && - block2->nextBlock->predecessors->block == block2 && - !block2->nextBlock->predecessors->nextLink - ) { - if ((val & 30) == 4) - instr->args[0].data.imm.value = val | 12; - else if ((val & 30) == 12) - instr->args[0].data.imm.value = val & 23; - instr->op = PC_BCCTR; - instr->argCount = 3; - deletepcode(block2->nextBlock->firstPCode); - changed = deleted = 1; - } - } - } - } - } - - if (deleted) - codesize = pccomputeoffsets(); - } while (changed); - - return codesize; -} - -static SInt32 insert_align_nops(Object *func, SInt32 codesize) { - PCodeBlock *block; - int changed; - PCodeBlock *prev; - - do { - changed = 0; - - for (block = pcbasicblocks; block; block = block->nextBlock) { - if ( - (block->flags & fPCBlockFlag6000) == fPCBlockFlag2000 && - (block->codeOffset & 7) && - block->pcodeCount < 8 && - (prev = block->prevBlock) && - !(prev->flags & fPCBlockFlag2000) - ) - { - if (prev->lastPCode && prev->lastPCode->op == PC_NOP && !(prev->lastPCode->flags & fSideEffects)) { - deletepcode(prev->lastPCode); - } else { - PCode *nop = makepcode(PC_NOP); - nop->flags &= ~fSideEffects; - appendpcode(prev, nop); - } - - codesize = pccomputeoffsets(); - changed = 1; - } - } - - if (changed) { - pclistblocks(CMangler_GetLinkName(func)->name, "AFTER INSERT ALIGN NOPs"); - if (codesize > 32766) { - insertlongbranches(32766); - codesize = pccomputeoffsets(); - } - } - - } while (changed); - - return codesize; -} - -SInt32 assemblefunction(Object *func, EntryPoint *entrypoints) { - void *tbdata; - GList *gl; - PCodeBlock *block; - PCode *instr; - SInt32 offset2; - SInt32 codesize; - SInt32 tbsize; - SInt32 offset; - SectionHandle section; - EntryPoint *ep; - WeirdOperand wop; - - codesize = pccomputeoffsets(); - if (codesize <= 0) - PPCError_Error(PPCErrorStr190, func->name->name); - - if (copts.peephole || copts.optimizationlevel >= 3) - codesize = optimizefinalbranches(codesize); - - if (codesize > 32766) { - insertlongbranches(32766); - codesize = pccomputeoffsets(); - } - - if (copts.function_align > 4) - codesize = insert_align_nops(func, codesize); - - tbsize = 0; - if (copts.traceback) - tbdata = generate_traceback(codesize, CMangler_GetLinkName(func)->name, &tbsize, func); - - if (func->section == SECT_DEFAULT) - func->section = SECT_TEXT; - - offset = tbsize; - section = ObjGen_DeclareCode(func, codesize + tbsize); - gl = ObjGen_GetSectionGList(section); - - codebase = gl->size; - AppendGListNoData(gl, codesize + tbsize); - - if (copts.filesyminfo) { - ObjGen_SymFunc(func); - ObjGen_Line(functionbodyoffset, 0); - ObjGen_DeclareSymInfo(); - } - - if (uses_globals && pic_base_reg) - ObjGen_DeclarePICBase(func, pic_base_pcodelabel->block->codeOffset); - - if (entrypoints) { - for (ep = entrypoints; ep; ep = ep->next) { - ObjGen_DeclareEntry(ep->object, ep->block->codeOffset); - } - } - - for (block = pcbasicblocks; block; block = block->nextBlock) { - for (offset2 = block->codeOffset, instr = block->firstPCode; instr; instr = instr->nextPCode, offset2 += 4) { - if (copts.filesyminfo && instr->sourceoffset != -1) - ObjGen_Line(instr->sourceoffset, offset2); - - *((UInt32 *) (*gl->data + codebase + offset2)) = assemblepcode(instr, offset2, &wop); - - if (wop.type != -1) - ObjGen_RelocateObj(section, offset2, wop.x2, wop.type); - } - } - - if (copts.filesyminfo) - ObjGenMach_SymFuncEnd(func, codesize); - - if (copts.traceback) - memcpy(*gl->data + codebase + codesize, tbdata, offset); - - if (copts.traceback) - return codesize + tbsize; - else - return codesize; -} |