From 9d985413ce2b60a1a8cf001913ee8dac81c03aac Mon Sep 17 00:00:00 2001 From: Ash Wolf Date: Fri, 13 Jan 2023 01:36:56 +0000 Subject: [PATCH] fix lots more issues, add endian conversions to ObjGenMachO, add 64-bit kludge to Switch.c --- compiler_and_linker/FrontEnd/C/CPrep.c | 126 +++++++++-------- .../FrontEnd/Common/CompilerTools.c | 67 +++++++++ compiler_and_linker/unsorted/CExprConvMatch.c | 2 +- compiler_and_linker/unsorted/CInline.c | 2 +- compiler_and_linker/unsorted/CInt64.c | 2 +- compiler_and_linker/unsorted/CMachine.c | 6 +- .../unsorted/FuncLevelAsmPPC.c | 2 +- compiler_and_linker/unsorted/InlineAsm.c | 6 +- compiler_and_linker/unsorted/InstrSelection.c | 4 +- .../unsorted/InterferenceGraph.c | 15 +- compiler_and_linker/unsorted/IroLoop.c | 4 +- .../unsorted/IroPointerAnalysisADTs.c | 3 + compiler_and_linker/unsorted/IroPropagate.c | 2 +- compiler_and_linker/unsorted/LoopDetection.c | 2 +- compiler_and_linker/unsorted/MachO.c | 129 ++++++++++++------ compiler_and_linker/unsorted/ObjGenMachO.c | 16 ++- compiler_and_linker/unsorted/PCode.c | 4 +- compiler_and_linker/unsorted/PCodeInfo.c | 86 +++++++++++- compiler_and_linker/unsorted/Peephole.c | 8 +- compiler_and_linker/unsorted/Switch.c | 7 +- compiler_and_linker/unsorted/UseDefChains.c | 4 +- includes/common.h | 1 - includes/compiler/CompilerTools.h | 18 +++ includes/compiler/PCodeInfo.h | 1 + includes/mwcc_decomp.h | 94 ------------- 25 files changed, 362 insertions(+), 249 deletions(-) delete mode 100644 includes/mwcc_decomp.h diff --git a/compiler_and_linker/FrontEnd/C/CPrep.c b/compiler_and_linker/FrontEnd/C/CPrep.c index 80472b1..36ba0f9 100644 --- a/compiler_and_linker/FrontEnd/C/CPrep.c +++ b/compiler_and_linker/FrontEnd/C/CPrep.c @@ -4137,7 +4137,6 @@ static void prependif(void) { } static void prepifskip(void) { - // this function does something very weird with its code generation that i can't match TStreamElement ts; short t; @@ -4146,78 +4145,75 @@ static void prepifskip(void) { case IfState_1: case IfState_3: case IfState_4: - while (1) { - t = prepskipnextchar(); - pos = nextcharpos; - switch (t) { - case 0: - if (tokenstacklevel > 0) { - poptokenseq(); - } else if (tokenstacklevel > 0 || pos >= prep_file_end) { - if (filesp > 0) { - popfile(); - } else { - was_prep_error = 0; - ts.tokenfile = ifstack[iflevel - 1].file; - ts.tokenoffset = ifstack[iflevel - 1].pos; - CError_SetErrorToken(&ts); - CError_ErrorTerm(CErrorStr119); - iflevel = 0; - return; - } + restart: + t = prepskipnextchar(); + pos = nextcharpos; + switch (t) { + case 0: + if (tokenstacklevel > 0) { + poptokenseq(); + } else if (tokenstacklevel > 0 || pos >= prep_file_end) { + if (filesp > 0) { + popfile(); } else { - CPrep_Error(CErrorStr105); + was_prep_error = 0; + ts.tokenfile = ifstack[iflevel - 1].file; + ts.tokenoffset = ifstack[iflevel - 1].pos; + CError_SetErrorToken(&ts); + CError_ErrorTerm(CErrorStr119); + iflevel = 0; + return; } - continue; - case '\r': - newline(); - continue; - case '"': - skipendoflinematch((StringPtr) pos, '"'); - continue; - case '\'': - skipendoflinematch((StringPtr) pos, '"'); - continue; - case '#': - t = prepskipnextchar(); - pos = nextcharpos; - switch (t) { - case '\r': - continue; - case 0: - CPrep_Error(CErrorStr102); - default: - pos = ReadIdentifier(pos - 1); - if (!strcmp("if", tkidentifier->name)) { - prepif(); - } else if (!strcmp("ifdef", tkidentifier->name)) { - prepifdef(); - } else if (!strcmp("ifndef", tkidentifier->name)) { - prepifndef(); - } else if (!strcmp("elif", tkidentifier->name)) { - prepelif(); - } else if (!strcmp("else", tkidentifier->name)) { - prepelse(); - } else if (!strcmp("endif", tkidentifier->name)) { - prependif(); - } else { - skipendofline(); - continue; - } - } - break; - default: - skipendofline(); - continue; - } - break; + } else { + CPrep_Error(CErrorStr105); + } + goto restart; + case '\r': + newline(); + goto restart; + case '"': + skipendoflinematch((StringPtr) pos, '"'); + goto restart; + case '\'': + skipendoflinematch((StringPtr) pos, '"'); + goto restart; + case '#': + t = prepskipnextchar(); + pos = nextcharpos; + switch (t) { + case '\r': + goto restart; + case 0: + CPrep_Error(CErrorStr102); + default: + pos = ReadIdentifier(pos - 1); + if (!strcmp("if", tkidentifier->name)) { + prepif(); + } else if (!strcmp("ifdef", tkidentifier->name)) { + prepifdef(); + } else if (!strcmp("ifndef", tkidentifier->name)) { + prepifndef(); + } else if (!strcmp("elif", tkidentifier->name)) { + prepelif(); + } else if (!strcmp("else", tkidentifier->name)) { + prepelse(); + } else if (!strcmp("endif", tkidentifier->name)) { + prependif(); + } else { + skipendofline(); + goto restart; + } + } + break; + default: + skipendofline(); + goto restart; } break; case IfState_2: default: return; } - return; } } diff --git a/compiler_and_linker/FrontEnd/Common/CompilerTools.c b/compiler_and_linker/FrontEnd/Common/CompilerTools.c index fff4809..272cd81 100644 --- a/compiler_and_linker/FrontEnd/Common/CompilerTools.c +++ b/compiler_and_linker/FrontEnd/Common/CompilerTools.c @@ -53,6 +53,69 @@ unsigned char *CTool_CtoPstr(char *cstr) { return (unsigned char *) cstr; } +#ifdef CW_64_BIT_SUPPORT +enum { PoolCapacity = 64 }; +typedef struct ITPPool { + void *pointers[PoolCapacity]; + UInt32 baseIndex; + UInt32 size; + struct ITPPool *next; +} ITPPool; +static ITPPool *poolHead; +static ITPPool *poolTail; + +void *CTool_ResolveIndexToPointer(UInt32 index) { + ITPPool *pool = poolHead; + + if (index == 0) + return NULL; + + while (pool && index >= PoolCapacity) { + pool = pool->next; + index -= PoolCapacity; + } + + if (pool && index < pool->size) + return pool->pointers[index]; + else + return NULL; +} + +UInt32 CTool_CreateIndexFromPointer(void *ptr) { + ITPPool *pool = poolTail; + UInt32 index; + + if (ptr == NULL) + return 0; + + if (!pool || pool->size >= PoolCapacity) { + pool = lalloc(sizeof(ITPPool)); + pool->size = 0; + if (poolTail) { + pool->baseIndex = poolTail->baseIndex + PoolCapacity; + poolTail->next = pool; + } else { + pool->baseIndex = 0; + // always reserve index 0 for NULL + pool->pointers[0] = NULL; + pool->size = 1; + poolHead = pool; + } + poolTail = pool; + } + + index = pool->baseIndex + pool->size; + pool->pointers[pool->size] = ptr; + pool->size++; + return index; +} + +static void CTool_ResetPointerPool(void) { + poolHead = NULL; + poolTail = NULL; +} +#endif + static void GListError(void) { if (GListErrorProc) GListErrorProc(); @@ -845,6 +908,10 @@ void freelheap(void) { blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); blockp = blockp->next; } + +#ifdef CW_64_BIT_SUPPORT + CTool_ResetPointerPool(); +#endif } } diff --git a/compiler_and_linker/unsorted/CExprConvMatch.c b/compiler_and_linker/unsorted/CExprConvMatch.c index 69e6651..c01f54b 100644 --- a/compiler_and_linker/unsorted/CExprConvMatch.c +++ b/compiler_and_linker/unsorted/CExprConvMatch.c @@ -1025,7 +1025,7 @@ static ENode *CExpr_UserConversion(ENode *expr, Type *type2, UInt32 qual2, Impli if (CExpr_StandardConversionMatch(expr, tmptype23, arg21->qual, 0, &sc1)) { if (object27) { - if (!object26->u.func.inst && !object27->u.func.inst) + if (object26->u.func.inst && !object27->u.func.inst) continue; if (CExpr_IsBetterStandardConv(&sc2, &sc1)) continue; diff --git a/compiler_and_linker/unsorted/CInline.c b/compiler_and_linker/unsorted/CInline.c index 7d3c2ef..4cd3c4b 100644 --- a/compiler_and_linker/unsorted/CInline.c +++ b/compiler_and_linker/unsorted/CInline.c @@ -2598,7 +2598,7 @@ static Statement *CInline_InlineFunctionStatement(Statement *stmt, Boolean *chan } *changed = 1; - CInline_ExpandStatements(object, stmt, funcdata, stmt->expr, label, NULL, 0); + return CInline_ExpandStatements(object, stmt, funcdata, stmt->expr, label, NULL, 0); } static Statement *CInline_ExtractInlineFunction(Statement *stmt) { diff --git a/compiler_and_linker/unsorted/CInt64.c b/compiler_and_linker/unsorted/CInt64.c index 449e068..a2ccaec 100644 --- a/compiler_and_linker/unsorted/CInt64.c +++ b/compiler_and_linker/unsorted/CInt64.c @@ -457,7 +457,7 @@ void CInt64_ConvertUInt32(CInt64 *i) { } void CInt64_ConvertInt16(CInt64 *i) { - i->lo = (SInt32) i->lo; + i->lo = (SInt16) i->lo; CInt64_Extend32(i); } diff --git a/compiler_and_linker/unsorted/CMachine.c b/compiler_and_linker/unsorted/CMachine.c index 4bde879..5849444 100644 --- a/compiler_and_linker/unsorted/CMachine.c +++ b/compiler_and_linker/unsorted/CMachine.c @@ -10,10 +10,10 @@ #include "compiler/objects.h" #include "compiler/types.h" -TypeIntegral stbool = {TYPEINT, 0, IT_BOOL}; +TypeIntegral stbool = {TYPEINT, 1, IT_BOOL}; TypeIntegral stchar = {TYPEINT, 1, IT_CHAR}; -TypeIntegral stsignedchar = {TYPEINT, 0, IT_SCHAR}; -TypeIntegral stunsignedchar = {TYPEINT, 0, IT_UCHAR}; +TypeIntegral stsignedchar = {TYPEINT, 1, IT_SCHAR}; +TypeIntegral stunsignedchar = {TYPEINT, 1, IT_UCHAR}; TypeIntegral stwchar = {TYPEINT, 4, IT_WCHAR_T}; TypeIntegral stsignedshort = {TYPEINT, 2, IT_SHORT}; TypeIntegral stunsignedshort = {TYPEINT, 2, IT_USHORT}; diff --git a/compiler_and_linker/unsorted/FuncLevelAsmPPC.c b/compiler_and_linker/unsorted/FuncLevelAsmPPC.c index 6122800..5cdab02 100644 --- a/compiler_and_linker/unsorted/FuncLevelAsmPPC.c +++ b/compiler_and_linker/unsorted/FuncLevelAsmPPC.c @@ -119,7 +119,7 @@ static void FuncAsm_PreScanDirectives(void) { cprep_eoltokens = 1; if (setjmp(InlineAsm_assemblererror) == 0) { - while (tk == TK_IDENTIFIER && (directive = InlineAsm_IsDirective(AssemblerType_0))) { + while (tk == TK_IDENTIFIER && (directive = InlineAsm_IsDirective(AssemblerType_1))) { InlineAsm_ProcessDirective(directive); if (tk == ';' || tk == TK_EOL) { diff --git a/compiler_and_linker/unsorted/InlineAsm.c b/compiler_and_linker/unsorted/InlineAsm.c index ba6d2f2..3594cb0 100644 --- a/compiler_and_linker/unsorted/InlineAsm.c +++ b/compiler_and_linker/unsorted/InlineAsm.c @@ -383,7 +383,7 @@ static void ScanOptionalLabel(void) { } } -static void ScanStatements(volatile short endToken, UInt8 mode) { +static void ScanStatements(volatile short endToken, AssemblerType mode) { if (setjmp(InlineAsm_assemblererror)) { while (tk != TK_EOL && tk != endToken && tk != '}' && tk) tk = lex(); @@ -445,11 +445,11 @@ static void ScanStatements(volatile short endToken, UInt8 mode) { } void InlineAsm_ScanStatements(volatile short endToken) { - ScanStatements(endToken, 0); + ScanStatements(endToken, AssemblerType_0); } void InlineAsm_ScanFunction(volatile short endToken) { - ScanStatements(endToken, 1); + ScanStatements(endToken, AssemblerType_1); } void InlineAsm_Assemble(void) { diff --git a/compiler_and_linker/unsorted/InstrSelection.c b/compiler_and_linker/unsorted/InstrSelection.c index 0ea8bf9..e49437f 100644 --- a/compiler_and_linker/unsorted/InstrSelection.c +++ b/compiler_and_linker/unsorted/InstrSelection.c @@ -1757,8 +1757,8 @@ void gen_COND(ENode *expr, short outputReg, short outputRegHi, Operand *output) emitpcode(PC_XOR, reg2, reg1, output->reg); reg3 = outputReg ? outputReg : ALLOC_GPR(); emitpcode(PC_SUBF, reg3, reg1, reg2); - op2.optype = OpndType_GPR; - op2.reg = reg3; + output->optype = OpndType_GPR; + output->reg = reg3; } return; } diff --git a/compiler_and_linker/unsorted/InterferenceGraph.c b/compiler_and_linker/unsorted/InterferenceGraph.c index a849d1a..cc78a63 100644 --- a/compiler_and_linker/unsorted/InterferenceGraph.c +++ b/compiler_and_linker/unsorted/InterferenceGraph.c @@ -55,9 +55,7 @@ static void buildinterferencematrix(void) { for (block = pcbasicblocks; block; block = block->nextBlock) { bitvectorcopy(vec, liveinfo[block->blockIndex].out, regs); for (instr = block->lastPCode; instr; instr = instr->prevPCode) { - op = instr->args; - i = instr->argCount; - while (i--) { + for (op = instr->args, i = instr->argCount; i--; op++) { if (PC_OP_IS_WRITE_ANY_REGISTER(op, coloring_class)) { reg = op->data.reg.reg; bitvectorclearbit(reg, vec); @@ -73,23 +71,19 @@ static void buildinterferencematrix(void) { } } } - op++; } - op = instr->args; - i = instr->argCount; - while (i--) { + for (op = instr->args, i = instr->argCount; i--; op++) { if (PC_OP_IS_READ_ANY_REGISTER(op, coloring_class)) { reg = op->data.reg.reg; if (bitvectorgetbit(reg, vec) == 0) op->data.reg.effect |= Effect4; bitvectorsetbit(reg, vec); } - op++; } if (coloring_class == RegClass_GPR) { - if (PCODE_FLAG_SET_F(instr) & (fIsRead | fIsWrite | fPCodeFlag40000)) { + if (PCODE_FLAG_SET_F(instr) & (fIsRead | fIsWrite | fPCodeFlag400000)) { if (instr->args[1].data.reg.reg >= n_real_registers[coloring_class]) makeinterfere(0, instr->args[1].data.reg.reg); if (PCODE_FLAG_SET_F(instr) & fUpdatesPtr) @@ -124,7 +118,7 @@ static void buildinterferencematrix(void) { op = instr->args; CError_ASSERT(219, instr->argCount != 0); - while (op->kind != PCOp_REGISTER && !(op->data.reg.effect & EffectWrite)) { + while (op->kind != PCOp_REGISTER || !(op->data.reg.effect & EffectWrite)) { i++; op++; CError_ASSERT(226, i <= instr->argCount); @@ -136,6 +130,7 @@ static void buildinterferencematrix(void) { for (j = 0; j < n_scratch_registers[coloring_class]; j++) makeinterfere(op->data.reg.reg, scratch_registers[coloring_class][j]); } + i++; op++; } } diff --git a/compiler_and_linker/unsorted/IroLoop.c b/compiler_and_linker/unsorted/IroLoop.c index 8a7f4fe..50c835f 100644 --- a/compiler_and_linker/unsorted/IroLoop.c +++ b/compiler_and_linker/unsorted/IroLoop.c @@ -1993,7 +1993,7 @@ IROLoop *ExtractLoopInfo(IRONode *fnode) { if (IS_LINEAR_DIADIC(scannd, ESHR) && (obj = IRO_IsVariable(scannd->u.diadic.left)) && - IRO_IsConstant(scannd->u.diadic.right)) { + IRO_IsIntConstant(scannd->u.diadic.right)) { for (scanind = FirstInd; scanind; scanind = scanind->next) { if (scanind->var->object == obj) { IRO_Dump("Induction has DIV: %s\n", obj->name->name); @@ -2004,7 +2004,7 @@ IROLoop *ExtractLoopInfo(IRONode *fnode) { if (IS_LINEAR_DIADIC(scannd, EAND) && (obj = IRO_IsVariable(scannd->u.diadic.left)) && - IRO_IsConstant(scannd->u.diadic.right)) { + IRO_IsIntConstant(scannd->u.diadic.right)) { for (scanind = FirstInd; scanind && obj; scanind = scanind->next) { if (scanind->var->object == obj) { IRO_Dump("Induction has MOD: %s\n", obj->name->name); diff --git a/compiler_and_linker/unsorted/IroPointerAnalysisADTs.c b/compiler_and_linker/unsorted/IroPointerAnalysisADTs.c index 54e59c8..744f58c 100644 --- a/compiler_and_linker/unsorted/IroPointerAnalysisADTs.c +++ b/compiler_and_linker/unsorted/IroPointerAnalysisADTs.c @@ -2,6 +2,9 @@ #include "compiler/IroMalloc.h" #include "compiler/CError.h" #include "compiler/CInt64.h" +#include "compiler/CParser.h" +#include "compiler/objects.h" +#include "compiler/types.h" // TODO: this should really be elsewhere (but where?) CW_INLINE UInt32 gcd(UInt32 a, UInt32 b) { diff --git a/compiler_and_linker/unsorted/IroPropagate.c b/compiler_and_linker/unsorted/IroPropagate.c index fb3a9ad..401250c 100644 --- a/compiler_and_linker/unsorted/IroPropagate.c +++ b/compiler_and_linker/unsorted/IroPropagate.c @@ -509,7 +509,7 @@ void IRO_ExpressionPropagation(void) { if (IRO_IsVariable(linear) && !(linear->flags & IROLF_Assigned)) { if ((var = IRO_FindVar(linear->u.monadic->u.node->data.objref, 0, 1))) { - for (ass = IRO_LastAssign; ass; ass = ass->next) { + for (ass = IRO_FirstAssign; ass; ass = ass->next) { if (ass->varIndex == var->index && Bv_IsBitSet(ass->index, IRO_Avail) && !PropagationHasDefsInUnorderedRegions(linear, ass->linear2)) { if (ass->linear2->type == IROLinearOperand && IRO_is_CPtypeequal(linear->rtype, ass->linear->u.diadic.left->rtype)) { ENode *enode = IRO_NewENode(ass->linear2->u.node->type); diff --git a/compiler_and_linker/unsorted/LoopDetection.c b/compiler_and_linker/unsorted/LoopDetection.c index 1d8244a..f1513e0 100644 --- a/compiler_and_linker/unsorted/LoopDetection.c +++ b/compiler_and_linker/unsorted/LoopDetection.c @@ -592,7 +592,7 @@ static void checkcountingloop(Loop *loop) { return; if (op12 != PC_CMP && op12 != PC_CMPL && op12 != PC_CMPI && op12 != PC_CMPLI) return; - if (prevpcode->args[1].data.reg.reg == pc8->args[0].data.reg.reg) + if (prevpcode->args[1].data.reg.reg != pc8->args[0].data.reg.reg) return; if ((loop->step = pc8->args[2].data.imm.value) == 0) return; diff --git a/compiler_and_linker/unsorted/MachO.c b/compiler_and_linker/unsorted/MachO.c index a0e11ae..18d91bb 100644 --- a/compiler_and_linker/unsorted/MachO.c +++ b/compiler_and_linker/unsorted/MachO.c @@ -255,13 +255,23 @@ static void ApplyRelocs(void) { ptr = (UInt32 *) ((*section->glist.data) + reloc->address); if (reloc->is_pcrel) { - if (!reloc->is_extern) - *ptr = (*ptr & opMask) | (argMask & (value - (reloc->address + section->section.addr) + (*ptr & argMask))); + if (!reloc->is_extern) { + *ptr = CTool_EndianConvertWord32( + (CTool_EndianConvertWord32(*ptr) & opMask) | + (argMask & (value - (reloc->address + section->section.addr) + (CTool_EndianConvertWord32(*ptr) & argMask)))); + } } else { - if (reloc->reltype == PPC_RELOC_PAIR) - *ptr = (*ptr & opMask) | (value & argMask); - else - *ptr = (*ptr & opMask) | (argMask & (value + (*ptr & argMask))); + if (reloc->reltype == PPC_RELOC_PAIR) { + *ptr = CTool_EndianConvertWord32( + (CTool_EndianConvertWord32(*ptr) & opMask) | + (value & argMask) + ); + } else { + *ptr = CTool_EndianConvertWord32( + (CTool_EndianConvertWord32(*ptr) & opMask) | + (argMask & (value + (CTool_EndianConvertWord32(*ptr) & argMask))) + ); + } } } } @@ -287,9 +297,41 @@ static void WriteSegLoadCommands(void) { MachOSection *section; for (segment = FirstSeg; segment; segment = segment->next) { +#ifdef ENDIAN_CONVERSION + struct segment_command c = segment->cmd; + c.cmd = CTool_EndianConvertWord32(c.cmd); + c.cmdsize = CTool_EndianConvertWord32(c.cmdsize); + c.vmaddr = CTool_EndianConvertWord32(c.vmaddr); + c.vmsize = CTool_EndianConvertWord32(c.vmsize); + c.fileoff = CTool_EndianConvertWord32(c.fileoff); + c.filesize = CTool_EndianConvertWord32(c.filesize); + c.maxprot = CTool_EndianConvertWord32(c.maxprot); + c.initprot = CTool_EndianConvertWord32(c.initprot); + c.nsects = CTool_EndianConvertWord32(c.nsects); + c.flags = CTool_EndianConvertWord32(c.flags); + AppendGListData(&ObjFile, &c, sizeof(c)); +#else AppendGListData(&ObjFile, &segment->cmd, sizeof(segment->cmd)); - for (section = segment->firstSection; section; section = section->next) +#endif + + for (section = segment->firstSection; section; section = section->next) { +#ifdef ENDIAN_CONVERSION + struct section c = section->section; + c.addr = CTool_EndianConvertWord32(c.addr); + c.size = CTool_EndianConvertWord32(c.size); + c.offset = CTool_EndianConvertWord32(c.offset); + c.align = CTool_EndianConvertWord32(c.align); + c.reloff = CTool_EndianConvertWord32(c.reloff); + c.nreloc = CTool_EndianConvertWord32(c.nreloc); + c.flags = CTool_EndianConvertWord32(c.flags); + c.reserved1 = CTool_EndianConvertWord32(c.reserved1); + c.reserved2 = CTool_EndianConvertWord32(c.reserved2); + + AppendGListData(&ObjFile, &c, sizeof(c)); +#else AppendGListData(&ObjFile, §ion->section, sizeof(section->section)); +#endif + } } } @@ -297,14 +339,14 @@ static void WriteSymtabLoadCommand(void) { struct symtab_command cmd; UInt32 total; - cmd.cmd = LC_SYMTAB; - cmd.cmdsize = sizeof(cmd); - cmd.symoff = FileOffset; + cmd.cmd = CTool_EndianConvertWord32(LC_SYMTAB); + cmd.cmdsize = CTool_EndianConvertWord32(sizeof(cmd)); + cmd.symoff = CTool_EndianConvertWord32(FileOffset); total = SymNum + NumStabs; cmd.nsyms = total; FileOffset += total * sizeof(struct nlist); - cmd.stroff = FileOffset; - cmd.strsize = StringTable.size; + cmd.stroff = CTool_EndianConvertWord32(FileOffset); + cmd.strsize = CTool_EndianConvertWord32(StringTable.size); AppendGListData(&ObjFile, &cmd, sizeof(cmd)); } @@ -329,15 +371,15 @@ static void WriteDynamicSymtabLoadCommand(void) { CError_ASSERT(652, (iundefsym + nundefsym) <= (SymNum + NumStabs)); - cmd.cmd = LC_DYSYMTAB; - cmd.cmdsize = sizeof(cmd); + cmd.cmd = CTool_EndianConvertWord32(LC_DYSYMTAB); + cmd.cmdsize = CTool_EndianConvertWord32(sizeof(cmd)); - cmd.ilocalsym = ilocalsym; - cmd.nlocalsym = nlocalsym; - cmd.iextdefsym = iextdefsym; - cmd.nextdefsym = nextdefsym; - cmd.iundefsym = iundefsym; - cmd.nundefsym = nundefsym; + cmd.ilocalsym = CTool_EndianConvertWord32(ilocalsym); + cmd.nlocalsym = CTool_EndianConvertWord32(nlocalsym); + cmd.iextdefsym = CTool_EndianConvertWord32(iextdefsym); + cmd.nextdefsym = CTool_EndianConvertWord32(nextdefsym); + cmd.iundefsym = CTool_EndianConvertWord32(iundefsym); + cmd.nundefsym = CTool_EndianConvertWord32(nundefsym); cmd.tocoff = 0; cmd.ntoc = 0; @@ -345,8 +387,8 @@ static void WriteDynamicSymtabLoadCommand(void) { cmd.nmodtab = 0; cmd.extrefsymoff = 0; cmd.nextrefsyms = 0; - cmd.indirectsymoff = IndirectSymbolTableOffset; - cmd.nindirectsyms = IndirectSymbolTable.size / 4; + cmd.indirectsymoff = CTool_EndianConvertWord32(IndirectSymbolTableOffset); + cmd.nindirectsyms = CTool_EndianConvertWord32(IndirectSymbolTable.size / 4); cmd.extreloff = 0; cmd.nextrel = 0; cmd.locreloff = 0; @@ -428,13 +470,13 @@ static void WriteRelocs(void) { case PPC_RELOC_BR24: case PPC_RELOC_HI16: case PPC_RELOC_PB_LA_PTR: - AppendGListLong(&ObjFile, reloc->address); + AppendGListLong(&ObjFile, CTool_EndianConvertWord32(reloc->address)); AppendGListLong(&ObjFile, - (reloc->value << 8) | + CTool_EndianConvertWord32((reloc->value << 8) | (reloc->is_pcrel << 7) | (length_code[reloc->length] << 5) | (reloc->is_extern << 4) | - reloc->reltype + reloc->reltype) ); break; case PPC_RELOC_PAIR: @@ -471,21 +513,21 @@ static void WriteRelocs(void) { pairType = 0; if (scatterFlag) { AppendGListLong(&ObjFile, - scatterFlag | + CTool_EndianConvertWord32(scatterFlag | (reloc->is_pcrel << 30) | (length_code[reloc->length] << 28) | (reloc->reltype << 24) | - reloc->address + reloc->address) ); - AppendGListLong(&ObjFile, reloc->value); + AppendGListLong(&ObjFile, CTool_EndianConvertWord32(reloc->value)); } else { combo = (reloc->value << 8) | (reloc->is_pcrel << 7) | (length_code[reloc->length] << 5) | reloc->reltype; - AppendGListLong(&ObjFile, reloc->address); - AppendGListLong(&ObjFile, combo); + AppendGListLong(&ObjFile, CTool_EndianConvertWord32(reloc->address)); + AppendGListLong(&ObjFile, CTool_EndianConvertWord32(combo)); } break; case PPC_RELOC_SECTDIFF: @@ -497,13 +539,13 @@ static void WriteRelocs(void) { pairType = reloc->reltype; pairValue = reloc->value; AppendGListLong(&ObjFile, - R_SCATTERED | + CTool_EndianConvertWord32(R_SCATTERED | (reloc->is_pcrel << 30) | (length_code[reloc->length] << 28) | (reloc->reltype << 24) | - reloc->address + reloc->address) ); - AppendGListLong(&ObjFile, reloc->value); + AppendGListLong(&ObjFile, CTool_EndianConvertWord32(reloc->value)); break; default: @@ -525,8 +567,10 @@ static void WriteIndirectSymbolTable(void) { COS_LockHandle(IndirectSymbolTable.data); ptr = (UInt32 *) *IndirectSymbolTable.data; - for (i = 0; i < MachO_NumIndirectSym(); ptr++, i++) + for (i = 0; i < MachO_NumIndirectSym(); ptr++, i++) { *ptr += NumStabs; + *ptr = CTool_EndianConvertWord32(*ptr); + } AppendGListData(&ObjFile, *IndirectSymbolTable.data, IndirectSymbolTable.size); COS_UnlockHandle(IndirectSymbolTable.data); @@ -543,13 +587,13 @@ static void WriteSymbolTable(void) { } for (symbol = FirstSym; symbol; symbol = symbol->next) { - nlist.n_strx = symbol->data.u.strx; + nlist.n_strx = CTool_EndianConvertWord32(symbol->data.u.strx); nlist.n_type = symbol->data.type; if (symbol->data.section) nlist.n_sect = symbol->data.section->num; else nlist.n_sect = 0; - nlist.n_desc = symbol->data.desc; + nlist.n_desc = CTool_EndianConvertWord16(symbol->data.desc); if ( symbol->data.type == N_STSYM || @@ -569,7 +613,7 @@ static void WriteSymbolTable(void) { CError_FATAL(1010); } - nlist.n_value = symbol->data.value; + nlist.n_value = CTool_EndianConvertWord32(symbol->data.value); AppendGListData(&ObjFile, &nlist, sizeof(nlist)); } } @@ -598,7 +642,8 @@ void MachO_Finish(void) { hdr.ncmds++; } - hdr.sizeofcmds = FileOffset - sizeof(hdr); + hdr.ncmds = CTool_EndianConvertWord32(hdr.ncmds); + hdr.sizeofcmds = CTool_EndianConvertWord32(FileOffset - sizeof(hdr)); AllocateAddresses(); ApplyRelocs(); @@ -615,10 +660,10 @@ void MachO_Finish(void) { InitGList(&ObjFile, 4096); - hdr.magic = MH_MAGIC; - hdr.cputype = CPU_TYPE_POWERPC; - hdr.cpusubtype = CPU_SUBTYPE_MC98000_ALL; - hdr.filetype = MH_OBJECT; + hdr.magic = CTool_EndianConvertWord32(MH_MAGIC); + hdr.cputype = CTool_EndianConvertWord32(CPU_TYPE_POWERPC); + hdr.cpusubtype = CTool_EndianConvertWord32(CPU_SUBTYPE_MC98000_ALL); + hdr.filetype = CTool_EndianConvertWord32(MH_OBJECT); hdr.flags = 0; AppendGListData(&ObjFile, &hdr, sizeof(hdr)); diff --git a/compiler_and_linker/unsorted/ObjGenMachO.c b/compiler_and_linker/unsorted/ObjGenMachO.c index 0a2c843..dfa77b8 100644 --- a/compiler_and_linker/unsorted/ObjGenMachO.c +++ b/compiler_and_linker/unsorted/ObjGenMachO.c @@ -921,7 +921,10 @@ void ObjGen_Finish(void) { if (value) { UInt32 *ptr = (UInt32 *) (*reloc->section->glist.data + reloc->offset); - *ptr = (*ptr & opMask) | (argMask & (value + (*ptr & argMask))); + *ptr = CTool_EndianConvertWord32( + (CTool_EndianConvertWord32(*ptr) & opMask) | + (argMask & (value + (CTool_EndianConvertWord32(*ptr) & argMask))) + ); } } else { switch (reloc->mwRelType) { @@ -969,7 +972,10 @@ void ObjGen_Finish(void) { if (value != 0) { UInt32 *ptr = (UInt32 *) (*reloc->section->glist.data + reloc->offset); - *ptr = (*ptr & opMask) | (argMask & (value + (*ptr & argMask))); + *ptr = CTool_EndianConvertWord32( + (CTool_EndianConvertWord32(*ptr) & opMask) | + (argMask & (value + (CTool_EndianConvertWord32(*ptr) & argMask))) + ); } if (nextRelType == PPC_RELOC_BR24) { @@ -1098,9 +1104,9 @@ static void declaredata(Object *object, char *data, OLinkList *olinklist, UInt32 SInt32 extflag; SInt32 id; - extflag = ObjGen_IsExternalVar(ObjGen_GetHashNodeRelocID(scan->obj, NULL, 0)); - id = CMangler_GetLinkName(scan->obj)->id; - ObjGen_Relocate(Sections[sectionID], offset + scan->offset, extflag + id, RT_4, MW_RELOC_0); + extflag = ObjGen_IsExternalVar(ObjGen_GetHashNodeRelocID(olinklist->obj, NULL, 0)); + id = CMangler_GetLinkName(olinklist->obj)->id; + ObjGen_Relocate(Sections[sectionID], offset + olinklist->offset, extflag + id, RT_4, MW_RELOC_0); olinklist = olinklist->next; } } else { diff --git a/compiler_and_linker/unsorted/PCode.c b/compiler_and_linker/unsorted/PCode.c index ee5b8e0..9fed4f6 100644 --- a/compiler_and_linker/unsorted/PCode.c +++ b/compiler_and_linker/unsorted/PCode.c @@ -1,12 +1,10 @@ #include "compiler/CompilerTools.h" #include "compiler/CFunc.h" +#include "compiler/Alias.h" #include "compiler/CodeGen.h" #include "compiler/PCode.h" #include "compiler/PCodeInfo.h" -// TODO: move me -extern void initialize_aliases(); - PCodeBlock *pcbasicblocks; PCodeBlock *pclastblock; PCodeBlock *prologue; diff --git a/compiler_and_linker/unsorted/PCodeInfo.c b/compiler_and_linker/unsorted/PCodeInfo.c index b11288b..fdfa71e 100644 --- a/compiler_and_linker/unsorted/PCodeInfo.c +++ b/compiler_and_linker/unsorted/PCodeInfo.c @@ -433,7 +433,7 @@ PCode *vformatpcode(short opcode, va_list argList) { CError_ASSERT(476, obj->otype == OT_OBJECT); arg->data.mem.obj = obj; arg->data.mem.offset = 0; - arg->arg = 1; + arg->arg = RefType_4; } break; @@ -769,7 +769,7 @@ int expectandformatoperand(PCodeArg *operand, PCOpKind expectedKind, char a3, in tmp = sprintf(buf, "%sB-B%ld+%ld", refis1 ? "-" : "", operand->data.labeldiff.labelB->block->blockIndex, operand->data.labeldiff.offset); } else { if (b_null) - tmp = sprintf(buf, "%sB%ld-%B+%ld", refis1 ? "-" : "", operand->data.labeldiff.labelA->block->blockIndex, operand->data.labeldiff.offset); + tmp = sprintf(buf, "%sB%ld-B+%ld", refis1 ? "-" : "", operand->data.labeldiff.labelA->block->blockIndex, operand->data.labeldiff.offset); else tmp = sprintf(buf, "%sB%ld-B%ld+%ld", refis1 ? "-" : "", operand->data.labeldiff.labelA->block->blockIndex, operand->data.labeldiff.labelB->block->blockIndex, operand->data.labeldiff.offset); } @@ -786,7 +786,12 @@ int expectandformatoperand(PCodeArg *operand, PCOpKind expectedKind, char a3, in } 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) { @@ -1146,15 +1151,83 @@ void formatoperands(PCode *pcode, char *buf, int showBasicBlocks) { } 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) { @@ -1261,7 +1334,14 @@ int nbytes_loaded_or_stored_by(PCode *pcode) { } 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) { diff --git a/compiler_and_linker/unsorted/Peephole.c b/compiler_and_linker/unsorted/Peephole.c index 0480c80..c9e4850 100644 --- a/compiler_and_linker/unsorted/Peephole.c +++ b/compiler_and_linker/unsorted/Peephole.c @@ -2346,7 +2346,7 @@ static void adjustforward(PCodeBlock *block) { if (PC_OP_IS_WRITE_REGISTER(op, RegClass_GPR, reg1)) flag2 = 1; - if (PC_OP_IS_REGISTER(op, RegClass_GPR, 0)) + if (PC_OP_IS_REGISTER(op, RegClass_CRFIELD, 0)) flag1 = 1; } } @@ -2389,13 +2389,13 @@ static void adjustforward(PCodeBlock *block) { break; } - if (PC_OP_IS_REGISTER(op, RegClass_GPR, 0)) + if (PC_OP_IS_REGISTER(op, RegClass_CRFIELD, 0)) flag = 1; } } } else if ( instr->op == PC_EXTSH && - (reg0 = instr->args[0].data.reg.reg) == (reg1 = instr->args[1].data.reg.reg) + (reg0 = instr->args[0].data.reg.reg) != (reg1 = instr->args[1].data.reg.reg) ) { short flag = 0; @@ -2428,7 +2428,7 @@ static void adjustforward(PCodeBlock *block) { break; } - if (PC_OP_IS_REGISTER(op, RegClass_GPR, 0)) + if (PC_OP_IS_REGISTER(op, RegClass_CRFIELD, 0)) flag = 1; } } diff --git a/compiler_and_linker/unsorted/Switch.c b/compiler_and_linker/unsorted/Switch.c index 8fd45b8..3b9d246 100644 --- a/compiler_and_linker/unsorted/Switch.c +++ b/compiler_and_linker/unsorted/Switch.c @@ -366,8 +366,7 @@ static Object *create_switch_table(void) { while (CInt64_LessEqual(value, range)) { while (CInt64_Greater(CInt64_Add(first, value), CInt64_Add(currange->min, currange->range))) currange++; - // HACK - this will not work properly on 64-bit systems - *outptr = (UInt32) currange->label; + *outptr = CTool_CreateIndexFromPointer(currange->label); value = CInt64_Add(value, cint64_one); outptr++; } @@ -420,7 +419,7 @@ static void generate_table(ENode *expr, SwitchInfo *info) { } } - if (FITS_IN_SHORT(CInt64_GetULong(&range))) { + if (!FITS_IN_SHORT(CInt64_GetULong(&range))) { short tmp = ALLOC_GPR(); load_immediate(tmp, CInt64_GetULong(&range)); emitpcode(PC_CMPL, 0, reg, tmp); @@ -511,7 +510,7 @@ void dumpswitchtables(Object *funcobj) { size = table->u.data.u.switchtable.size; array = (UInt32 *) table->u.data.u.switchtable.data; while (size--) { - *array = CTool_EndianConvertWord32(((PCodeLabel *) *array)->block->codeOffset); + *array = CTool_EndianConvertWord32(((PCodeLabel *) CTool_ResolveIndexToPointer(*array))->block->codeOffset); array++; } diff --git a/compiler_and_linker/unsorted/UseDefChains.c b/compiler_and_linker/unsorted/UseDefChains.c index 7d87fa9..3ad955b 100644 --- a/compiler_and_linker/unsorted/UseDefChains.c +++ b/compiler_and_linker/unsorted/UseDefChains.c @@ -295,7 +295,7 @@ static void computeusedeflists(int flag) { def->v.arg = 0; def->v.u.object = object; list = oalloc(sizeof(RegUseOrDef)); - list->id = useID; + list->id = defID; tmp = findobjectusedef(object); list->next = tmp->defs; tmp->defs = list; @@ -427,7 +427,7 @@ static void computelocalusedefinfo(void) { bitvectorclearbit(list->id, defvec0); } } else if (def->v.arg == 0) { - oud = findobjectusedef(use->v.u.object); + oud = findobjectusedef(def->v.u.object); for (list = oud->uses; list; list = list->next) { if (may_alias(pcode, Uses[list->id].pcode)) { if (Uses[list->id].pcode->block != block) diff --git a/includes/common.h b/includes/common.h index ba9b54c..9ea51fb 100644 --- a/includes/common.h +++ b/includes/common.h @@ -15,7 +15,6 @@ #ifdef __MWERKS__ #define macintosh -//#include #define CW_PASCAL pascal #undef toupper #undef tolower diff --git a/includes/compiler/CompilerTools.h b/includes/compiler/CompilerTools.h index b218925..1338f29 100644 --- a/includes/compiler/CompilerTools.h +++ b/includes/compiler/CompilerTools.h @@ -3,6 +3,10 @@ #include "compiler/common.h" +#ifdef __LITTLE_ENDIAN__ +#define ENDIAN_CONVERSION +#endif + extern void CompilerGetPString(short index, unsigned char *string); extern void CompilerGetCString(short index, char *string); extern unsigned char *CTool_CtoPstr(char *cstr); @@ -49,6 +53,20 @@ struct GList { extern long hash_name_id; extern HashNameNode **name_hash_nodes; + +#ifdef __LP64__ +#define CW_64_BIT_SUPPORT +#endif + +// These don't exist in the original source, but are kind of necessary in the 2020s +#ifdef CW_64_BIT_SUPPORT +extern void *CTool_ResolveIndexToPointer(UInt32 index); +extern UInt32 CTool_CreateIndexFromPointer(void *ptr); +#else +#define CTool_ResolveIndexToPointer(index) ((void *) (index)) +#define CTool_CreateIndexFromPointer(ptr) ((UInt32) (ptr)) +#endif + extern void (*GListErrorProc)(void); extern short InitGList(GList *gl, SInt32 size); diff --git a/includes/compiler/PCodeInfo.h b/includes/compiler/PCodeInfo.h index 330a422..bc29b26 100644 --- a/includes/compiler/PCodeInfo.h +++ b/includes/compiler/PCodeInfo.h @@ -17,6 +17,7 @@ typedef enum { PCOp_PLACEHOLDEROPERAND } PCOpKind; +// unify me with RefType? typedef enum { PCOpMemory0 = 0, PCOpMemory1 = 1 diff --git a/includes/mwcc_decomp.h b/includes/mwcc_decomp.h deleted file mode 100644 index 312c858..0000000 --- a/includes/mwcc_decomp.h +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once -#include "common.h" -#include "oslib.h" -#include "macemul.h" -#include "plugin.h" - -#define OPTION_ASSERT(cond) do { if (!!(cond) == 0) { printf("%s:%u: failed assertion\n", __FILE__, __LINE__); abort(); } } while(0) - -#ifdef __cplusplus -extern "C" { -#endif - -/********************************/ -/* command_line/CmdLine/Src/Clients/CLStaticMain.c */ -extern int main(int argc, const char **argv); - -/********************************/ -/* ??? */ -extern int AddFileTypeMappingList(void *a, void *b); // TODO sig -extern void UseFileTypeMappings(void *a); // TODO sig -extern OSErr SetMacFileType(const FSSpec *fss, void *a); // TODO sig -extern OSErr GetMacFileType(const FSSpec *fss, void *a); // TODO sig - -/********************************/ -/* Might be cc-mach-ppc-mw.c? */ -extern void GetStaticTarget(OSType *cpu, OSType *os); -extern void GetStaticPluginType(OSType *language, OSType *plugintype); -extern void GetStaticParserPluginType(OSType *style); -extern int RegisterStaticTargetResources(void); -extern int RegisterStaticTargetPlugins(void); - -/********************************/ -/* Might be ParserGlue-mach-ppc-cc.c? */ -extern int RegisterStaticParserToolInfo(void); - -/********************************/ -/* Might be cc-mach-ppc.c? */ -extern int RegisterStaticCompilerPlugin(void); -extern int RegisterCompilerResources(void); - -/********************************/ -/* libimp-mach-ppc.c */ -// some statics here -extern int RegisterStaticLibImporterPlugin(void); -extern int RegisterLibImporterResources(void); - -/********************************/ -/* TargetOptimizer-ppc-mach.c */ -extern int TargetSetOptFlags(SInt16 val, Boolean set); -extern void TargetDisplayOptimizationOptions(Handle txt); -extern void TargetSetPragmaOptimizationsToUnspecified(void); - -/********************************/ -/* OptimizerHelpers.c */ -extern int SetPragmaOptimizationsToUnspecified(void); -extern int SetOptFlags(char *opt, void *str, ...); // two unknown args -extern int DisplayOptimizationOptions(void); - -/********************************/ -/* Unk name lol */ -extern int TargetSetWarningFlags(SInt16 val, Boolean set); -extern int TargetDisplayWarningOptions(Handle txt); - -/********************************/ -/* WarningHelpers.c */ -extern int SetWarningFlags(char *opt, void *str, ...); // two unknown args -extern int DisplayWarningOptions(void); - -/********************************/ -/* CCompiler.c */ -extern CWPLUGIN_ENTRY(MWC_main)(CWPluginContext context); - -// LOTS OF STUFF - -/********************************/ -/* StaticParserGlue.c */ -extern int RegisterStaticParserPlugins(void); -extern int RegisterStaticParserResources(void); - -/********************************/ -/* CmdLineBuildDate.c */ -extern char CMDLINE_BUILD_DATE[]; -extern char CMDLINE_BUILD_TIME[]; - - -/********************************/ -/* MISC */ -extern char cmdline_build_date[32]; -extern char cmdline_build_time[32]; - - -#ifdef __cplusplus -} -#endif