diff options
author | Ash Wolf <ninji@wuffs.org> | 2022-10-25 20:30:28 +0100 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2022-10-25 20:30:28 +0100 |
commit | d0b9848c54e6f85ab713f059dcd1ddef7e57caa6 (patch) | |
tree | 5bdb9dbf6c853780bc444dc92bf6f9fa3a95742a /compiler_and_linker/unsorted | |
parent | 685f22a6a0a5403c76316a2390c021a7b0f7597d (diff) | |
download | MWCC-d0b9848c54e6f85ab713f059dcd1ddef7e57caa6.tar.gz MWCC-d0b9848c54e6f85ab713f059dcd1ddef7e57caa6.zip |
a bunch of compiler stuff
Diffstat (limited to 'compiler_and_linker/unsorted')
-rw-r--r-- | compiler_and_linker/unsorted/CCompiler.c | 255 | ||||
-rw-r--r-- | compiler_and_linker/unsorted/CError.c | 1096 | ||||
-rw-r--r-- | compiler_and_linker/unsorted/CInt64.c | 892 | ||||
-rw-r--r-- | compiler_and_linker/unsorted/CMachine.c | 1499 | ||||
-rw-r--r-- | compiler_and_linker/unsorted/CPrec.c | 2142 |
5 files changed, 5884 insertions, 0 deletions
diff --git a/compiler_and_linker/unsorted/CCompiler.c b/compiler_and_linker/unsorted/CCompiler.c new file mode 100644 index 0000000..d496389 --- /dev/null +++ b/compiler_and_linker/unsorted/CCompiler.c @@ -0,0 +1,255 @@ +#include "compiler/common.h" +#include "compiler.h" +#include "compiler/types.h" +#include "pref_structs.h" +#include "compiler/CompilerTools.h" + +Boolean systemHandles; + +static Boolean using_license_manager; +Boolean crippled; +SInt32 license_cookie; +CParams cparams; + +// TODO move me to CParser.c, or maybe CMachine.c? +Type sttemplexpr = {TYPETEMPLDEPEXPR, 0}; +Type stillegal = {TYPEILLEGAL, 1}; +Type stvoid = {TYPEVOID, 0}; +TypePointer void_ptr = {TYPEPOINTER, 0, &stvoid, 0}; +TypeFunc rt_func = {TYPEFUNC, 0, NULL, NULL, &stvoid, 0, 0}; +// TODO move me to CParser.c + +static void get_extension(ConstStringPtr src, char *dst) { + int ep; + + dst[0] = 0; + for (ep = src[0]; src[ep] != '.'; ep--) {} + + if (ep >= 2) { + int x; + for (x = 0; (x + ep) <= src[0]; x++) + dst[x] = src[x + ep]; + dst[x] = 0; + } +} + +static int setup_param_block(CWPluginContext context) { + static char target_name[128]; + CWTargetInfo tinfo; + + memset(&cparams, 0, sizeof(CParams)); + cparams.context = context; + + if (CWGetPluginRequest(context, &cparams.pluginRequest) != cwNoErr) + return 0; + if (CWGetAPIVersion(context, &cparams.apiVersion) != cwNoErr) + return 0; + if (CWGetProjectFile(context, &cparams.projectFile) != cwNoErr) + return 0; + if (CWGetProjectFileCount(context, &cparams.projectFileCount) != cwNoErr) + return 0; + if (CWGetMainFileNumber(context, &cparams.mainFileNumber) != cwNoErr) + return 0; + if (CWGetMainFileSpec(context, &cparams.mainFileSpec) != cwNoErr) + return 0; + if (CWGetMainFileText(context, &cparams.mainFileText, &cparams.mainFileTextLength) != cwNoErr) + return 0; + if (CWIsPrecompiling(context, &cparams.isPrecompiling) != cwNoErr) + return 0; + if (CWIsAutoPrecompiling(context, &cparams.isAutoPrecompiling) != cwNoErr) + return 0; + if (CWIsPreprocessing(context, &cparams.isPreprocessing) != cwNoErr) + return 0; + if (CWIsGeneratingDebugInfo(context, &cparams.isGeneratingDebugInfo) != cwNoErr) + return 0; + if (CWIsCachingPrecompiledHeaders(context, &cparams.isCachingPrecompiledHeaders) != cwNoErr) + return 0; + if (CWGetBrowseOptions(context, &cparams.browseOptions) != cwNoErr) + return 0; + cparams.field276 = cparams.isPreprocessing == 0; + if (CWGetMainFileID(context, &cparams.mainFileID) != cwNoErr) + return 0; + if (CWGetTargetInfo(context, &tinfo) != cwNoErr) + return 0; + + cparams.targetOS = tinfo.targetOS; + cparams.targetCPU = tinfo.targetCPU; + cparams.targetName = target_name; + return CWGetTargetName(context, target_name, sizeof(target_name)) == cwNoErr; +} + +static short store_compile_results() { + CWResult result; + + if (cparams.objectDataHandle) + CWSecretAttachHandle(cparams.context, cparams.objectDataHandle, &cparams.objectdata.objectdata); + if (cparams.browseDataHandle) + CWSecretAttachHandle(cparams.context, cparams.browseDataHandle, &cparams.objectdata.browsedata); + + if (cparams.isPreprocessing) { + if (cparams.objectdata.objectdata) { + CWNewTextDocumentInfo docinfo; + memset(&docinfo, 0, sizeof(CWNewTextDocumentInfo)); + docinfo.text = cparams.objectdata.objectdata; + cparams.objectdata.objectdata = NULL; + result = CWCreateNewTextDocument(cparams.context, &docinfo); + } + } else { + result = CWStoreObjectData(cparams.context, cparams.mainFileNumber, &cparams.objectdata); + } + + return result; +} + +static void initialize_compiler_options(CParams *params) { + static PFrontEndC pFrontEnd; + PWarningC pWarningC; + PGlobalOptimizer pGlobalOptimizer; + Handle prefsdata; + char extension[256]; + + memclrw(&copts, sizeof(COpts)); + + CWSecretGetNamedPreferences(cparams.context, "C/C++ Compiler", &prefsdata); + pFrontEnd = *((PFrontEndC *) *prefsdata); + + copts.little_endian = 0; + copts.cplusplus = 1; + copts.objective_c = pFrontEnd.objective_c; + get_extension(params->mainFileSpec.name, extension); + if (!strcmp(extension, ".c") || !strcmp(extension, ".h") || !strcmp(extension, ".pch")) { + copts.cplusplus = pFrontEnd.cplusplus; + } else if (!strcmp(extension, ".m")) { + copts.cplusplus = pFrontEnd.cplusplus; + copts.objective_c = 1; + } else if (!strcmp(extension, ".mm") || !strcmp(extension, ".M")) { + copts.cplusplus = 1; + copts.objective_c = 1; + } + + copts.require_prototypes = pFrontEnd.checkprotos; + copts.ARM_conform = pFrontEnd.arm; + copts.ARM_scoping = pFrontEnd.arm; + copts.trigraphs = pFrontEnd.trigraphs; + copts.only_std_keywords = pFrontEnd.onlystdkeywords; + copts.enumsalwaysint = pFrontEnd.enumsalwaysint; + copts.mpwc_relax = pFrontEnd.mpwpointerstyle; + copts.ANSI_strict = pFrontEnd.ansistrict; + copts.mpwc_newline = pFrontEnd.mpwcnewline; + copts.exceptions = pFrontEnd.enableexceptions; + copts.dont_reuse_strings = pFrontEnd.dontreusestrings; + copts.pool_strings = pFrontEnd.poolstrings; + copts.dont_inline = pFrontEnd.dontinline; + copts.useRTTI = pFrontEnd.useRTTI; + copts.oldprefixname = pFrontEnd.oldprefixname; + copts.multibyteaware = pFrontEnd.multibyteaware; + copts.unsignedchars = pFrontEnd.unsignedchars; + copts.autoinline = pFrontEnd.autoinline; + copts.direct_to_som = pFrontEnd.direct_to_som; + copts.som_env_check = pFrontEnd.som_env_check; + copts.booltruefalse = pFrontEnd.booltruefalse; + copts.always_inline = pFrontEnd.alwaysinline; + copts.inlinelevel = pFrontEnd.inlinelevel; + copts.wchar_type = pFrontEnd.wchar_type; + copts.ecplusplus = pFrontEnd.ecplusplus; + copts.defer_codegen = pFrontEnd.defer_codegen; + copts.inline_max_size = 512; + copts.inline_max_total_size = 100000; + + CWSecretGetNamedPreferences(cparams.context, "C/C++ Warnings", &prefsdata); + pWarningC = *((PWarningC *) *prefsdata); + + copts.warn_illpragma = pWarningC.warn_illpragma; + copts.warn_emptydecl = pWarningC.warn_emptydecl; + copts.warn_possunwant = pWarningC.warn_possunwant; + copts.warn_unusedvar = pWarningC.warn_unusedvar; + copts.warn_unusedarg = pWarningC.warn_unusedarg; + copts.warn_extracomma = pWarningC.warn_extracomma; + copts.pedantic = pWarningC.pedantic; + copts.warningerrors = pWarningC.warningerrors; + copts.warn_hidevirtual = pWarningC.warn_hidevirtual; + copts.warn_implicitconv = pWarningC.warn_implicitconv; + copts.warn_notinlined = pWarningC.warn_notinlined; + copts.warn_structclass = pWarningC.warn_structclass; + + CWSecretGetNamedPreferences(cparams.context, "PPC Global Optimizer", &prefsdata); + pGlobalOptimizer = *((PGlobalOptimizer *) *prefsdata); + + copts.optimizationlevel = pGlobalOptimizer.optimizationlevel; + copts.optimize_for_size = (Boolean) (pGlobalOptimizer.optfor == 1); + + copts.crippled = crippled; + copts.loop_unroll_count = 8; + copts.loop_unroll_size_threshold = 100; + copts.isGeneratingDebugInfo = params->isGeneratingDebugInfo; + copts.pchCreator = CWFOURCHAR('C','W','I','E'); + copts.pchType = CWFOURCHAR('M','M','C','H'); + copts.text = CWFOURCHAR('T','E','X','T'); +} + +static void GetLicense() { + if (!license_cookie) { + crippled = 1; + CWCheckoutLicense(cparams.context, "MacOS_Plugins_MacOS_Unlimited", "7", 2, NULL, &license_cookie); + if (license_cookie) { + CWCheckinLicense(cparams.context, license_cookie); + crippled = 0; + } + + CWCheckoutLicense(cparams.context, "MacOS_Plugins_MacOS_Limited", "7", 0, NULL, &license_cookie); + using_license_manager = 1; + } +} + +static void ReleaseLicense() { + if (license_cookie && using_license_manager) + CWCheckinLicense(cparams.context, license_cookie); + using_license_manager = 0; + license_cookie = 0; +} + +CWPLUGIN_ENTRY(MWC_main)(CWPluginContext context) { + CWResult result; + SInt32 request; + + result = cwNoErr; + CWGetPluginRequest(context, &request); + + switch (request) { + case reqInitialize: + cparams.context = context; + license_cookie = 0; + CodeGen_InitCompiler(); + break; + case reqTerminate: + cparams.context = context; + CodeGen_TermCompiler(); + ReleaseLicense(); + break; + case reqCompile: + setup_param_block(context); + GetLicense(); + if (license_cookie) { + initialize_compiler_options(&cparams); + CodeGen_UpdateOptimizerOptions(); + CodeGen_InitBackEndOptions(); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + if (C_Compiler(&cparams)) + result = store_compile_results(); + else + result = cwErrRequestFailed; + } else { + result = cwErrSilent; + } + break; + } + + return CWDonePluginRequest(context, result); +} + +void PrintProgressFunction(const char *str) { + char buf[96]; + sprintf(buf, "Compiling function:\t%.64s", str); + CWShowStatus(cparams.context, buf, ""); +} diff --git a/compiler_and_linker/unsorted/CError.c b/compiler_and_linker/unsorted/CError.c new file mode 100644 index 0000000..e7493f3 --- /dev/null +++ b/compiler_and_linker/unsorted/CError.c @@ -0,0 +1,1096 @@ +#include "cos.h" +#include "compiler/CError.h" +#include "compiler/CInt64.h" +#include "compiler/CompilerTools.h" +#include "compiler/enode.h" +#include "compiler/objc.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" +#include "compiler/templates.h" +#include "compiler/tokens.h" +#include "compiler.h" + +TStreamElement *cerror_locktoken; +static TStreamElement *cerror_token; +static short cerror_errorcount; +static SInt32 cerror_lasterrorline; +char cerror_synchdata[32]; +short cerror_synchoffset; +int CError_BreakPointcount; + +void CError_Init() { + cerror_errorcount = 0; + cerror_lasterrorline = -1; + cerror_token = 0; + cerror_locktoken = 0; +} + +void CError_SetErrorToken(TStreamElement *token) { + if (token && token->tokenfile) + cerror_token = token; +} + +void CError_SetNullErrorToken() { + cerror_token = (TStreamElement *) -1; +} + +void CError_LockErrorPos(TStreamElement *token, TStreamElement **saved) { + *saved = cerror_locktoken; + if (token && token->tokenfile) + cerror_locktoken = token; +} + +void CError_UnlockErrorPos(TStreamElement **saved) { + cerror_locktoken = *saved; +} + +void CError_ResetErrorSkip() { + cerror_lasterrorline = -1; +} + +void CError_GetErrorString(char *buf, short code) { +#line 142 + CError_ASSERT(code >= CErrorStr100 && code < CErrorStrMAX); + COS_GetString(buf, 10000, code - 99); +} + +void CError_BufferInit(CErrorBuffer *eb, char *buf, SInt32 bufSize) { + eb->start = eb->end = buf; + eb->size = eb->remaining = bufSize - 1; +} + +void CError_BufferGrow(CErrorBuffer *eb, SInt32 amount) { + char *newBuf; + + newBuf = lalloc(eb->size + amount); + memcpy(newBuf, eb->start, eb->size); + eb->start = newBuf; + eb->end = newBuf + eb->size - eb->remaining; + eb->size += amount; + eb->remaining += amount; +} + +void CError_BufferAppendChar(CErrorBuffer *eb, char ch) { + if (eb) { + if (!eb->remaining) + CError_BufferGrow(eb, 256); + *(eb->end++) = ch; + eb->remaining--; + } +} + +void CError_BufferAppendString(CErrorBuffer *eb, const char *str) { + size_t len; + + if (eb) { + len = strlen(str); + if (eb->remaining < len) + CError_BufferGrow(eb, len); + memcpy(eb->end, str, len); + eb->end += len; + eb->remaining -= len; + } +} + +void CError_BufferTerminate(CErrorBuffer *eb) { + if (eb->remaining == 0) + CError_BufferGrow(eb, 1); + *eb->end = 0; + eb->remaining = 0; +} + +void CError_BufferAppendQualifier(CErrorBuffer *eb, UInt32 qual) { + if (qual & Q_PASCAL) + CError_BufferAppendString(eb, "pascal "); + if (qual & Q_CONST) + CError_BufferAppendString(eb, "const "); + if (qual & Q_VOLATILE) + CError_BufferAppendString(eb, "volatile "); + if (qual & Q_EXPLICIT) + CError_BufferAppendString(eb, "explicit "); + if (qual & Q_RESTRICT) + CError_BufferAppendString(eb, "restrict "); +} + +void CError_BufferAppendTemplArgExpr(CErrorBuffer *eb, ENode *node) { + char buf[32]; + + if (node) { + switch (node->type) { + case EINTCONST: + CInt64_PrintDec(buf, node->data.intval); + CError_BufferAppendString(eb, buf); + return; + case EOBJREF: + CError_BufferAppendChar(eb, '&'); + CError_AppendObjectName(eb, node->data.objref); + return; + } + } + + CError_BufferAppendString(eb, "{targ_expr}"); +} + +void CError_BufferAppendTemplArg(CErrorBuffer *eb, TemplArg *targ) { + switch (targ->pid.type) { + case TPT_TYPE: + CError_BufferAppendType(eb, targ->data.typeparam.type, targ->data.typeparam.qual); + break; + case TPT_NONTYPE: + CError_BufferAppendTemplArgExpr(eb, targ->data.paramdecl.expr); + break; + case TPT_TEMPLATE: + CError_BufferAppendType(eb, targ->data.ttargtype, 0); + break; + default: +#line 300 + CError_FATAL(); + } +} + +void CError_BufferAppendTemplArgs(CErrorBuffer *eb, TemplArg *targs) { + if (targs) { + CError_BufferAppendChar(eb, '<'); + while (targs) { + CError_BufferAppendTemplArg(eb, targs); + if (targs->next) + CError_BufferAppendString(eb, ", "); + targs = targs->next; + } + CError_BufferAppendChar(eb, '>'); + } +} + +void CError_BufferAppendNameSpace(CErrorBuffer *eb, NameSpace *nspace) { + while (nspace) { + if (nspace->name) { + CError_BufferAppendNameSpace(eb, nspace->parent); + if (nspace->theclass) { + CError_BufferAppendString(eb, nspace->theclass->classname->name); + if (nspace->theclass->flags & CLASS_FLAGS_800) + CError_BufferAppendTemplArgs( + eb, + !TEMPL_CLASS_INST(nspace->theclass)->oargs ? TEMPL_CLASS_INST(nspace->theclass)->inst_args : TEMPL_CLASS_INST(nspace->theclass)->oargs + ); + } else { + CError_BufferAppendString(eb, nspace->name->name); + } + CError_BufferAppendString(eb, "::"); + return; + } + nspace = nspace->parent; + } +} + +void CError_BufferAppendPType(CErrorBuffer *eb, Type *ty) { + switch (ty->type) { + case TYPEPOINTER: + CError_BufferAppendPType(eb, TYPE_POINTER(ty)->target); + if (TYPE_POINTER(ty)->qual & Q_REFERENCE) + CError_BufferAppendString(eb, "&"); + else + CError_BufferAppendString(eb, "*"); + CError_BufferAppendQualifier(eb, TYPE_POINTER(ty)->qual); + break; + case TYPEMEMBERPOINTER: + CError_BufferAppendPType(eb, TYPE_MEMBER_POINTER(ty)->ty1); + CError_BufferAppendType(eb, TYPE_MEMBER_POINTER(ty)->ty2, 0); + CError_BufferAppendString(eb, "::*"); + CError_BufferAppendQualifier(eb, TYPE_MEMBER_POINTER(ty)->qual); + break; + } +} + +void CError_BufferAppendTemplDepType(CErrorBuffer *eb, TypeTemplDep *type) { + char buf[64]; + switch (type->dtype) { + case TEMPLDEP_ARGUMENT: + if (type->u.pid.nindex) + sprintf(buf, "T%ld_%ld", type->u.pid.nindex, type->u.pid.index); + else + sprintf(buf, "T%ld", type->u.pid.index); + CError_BufferAppendString(eb, buf); + break; + case TEMPLDEP_QUALNAME: + CError_BufferAppendTemplDepType(eb, type->u.qual.type); + CError_BufferAppendString(eb, "::"); + CError_BufferAppendString(eb, type->u.qual.name->name); + break; + case TEMPLDEP_TEMPLATE: + CError_BufferAppendType(eb, (Type *) type->u.templ.templ, 0); + CError_BufferAppendTemplArgs(eb, type->u.templ.args); + break; + case TEMPLDEP_ARRAY: + CError_BufferAppendType(eb, type->u.array.type, 0); + CError_BufferAppendChar(eb, '['); + CError_BufferAppendTemplArgExpr(eb, type->u.array.index); + CError_BufferAppendChar(eb, ']'); + break; + case TEMPLDEP_QUALTEMPL: + CError_BufferAppendTemplDepType(eb, type->u.qualtempl.type); + CError_BufferAppendString(eb, "::"); + CError_BufferAppendTemplArgs(eb, type->u.qualtempl.args); + break; + case TEMPLDEP_BITFIELD: + CError_BufferAppendType(eb, type->u.bitfield.type, 0); + CError_BufferAppendChar(eb, '['); + CError_BufferAppendTemplArgExpr(eb, type->u.bitfield.size); + CError_BufferAppendChar(eb, ']'); + break; + default: +#line 463 + CError_FATAL(); + } +} + +void CError_BufferAppendFuncArgs(CErrorBuffer *eb, TypeFunc *tfunc, Boolean isMethod) { + // not matching - weirdness with referencing string constants + FuncArg *arg; + UInt32 qual; + + qual = 0; + CError_BufferAppendChar(eb, '('); + if ((arg = tfunc->args)) { + if (isMethod) { + qual = arg->qual; + arg = arg->next; + if (arg) + arg = arg->next; + } else if ((tfunc->flags & FUNC_FLAGS_METHOD) && !TYPE_METHOD(tfunc)->x26) { + qual = arg->qual; + arg = arg->next; + if (arg) { + if ((tfunc->flags & FUNC_FLAGS_2000) || ((tfunc->flags & FUNC_FLAGS_1000) && (TYPE_METHOD(tfunc)->theclass->flags & CLASS_FLAGS_20))) + arg = arg->next; + } + } + + while (arg) { + if (arg == &elipsis || arg == &oldstyle) { + CError_BufferAppendString(eb, "..."); + break; + } else { + CError_BufferAppendType(eb, arg->type, arg->qual); + } + + if (!arg->next) { + CError_BufferAppendString(eb, ", "); + break; + } + } + } + CError_BufferAppendChar(eb, ')'); + if (qual) + CError_BufferAppendQualifier(eb, qual); +} + +void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { + // not matching - register issues + char buf[16]; + Type *scan, *scan2; + + switch (ty->type) { + case TYPEVOID: + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendString(eb, "void"); + break; + case TYPEINT: + case TYPEFLOAT: + CError_BufferAppendQualifier(eb, qual); + switch (TYPE_INTEGRAL(ty)->integral) { + case IT_BOOL: + CError_BufferAppendString(eb, "bool"); + break; + case IT_CHAR: + CError_BufferAppendString(eb, "char"); + break; + case IT_UCHAR: + CError_BufferAppendString(eb, "unsigned char"); + break; + case IT_SCHAR: + CError_BufferAppendString(eb, "signed char"); + break; + case IT_WCHAR_T: + CError_BufferAppendString(eb, "wchar_t"); + break; + case IT_SHORT: + CError_BufferAppendString(eb, "short"); + break; + case IT_USHORT: + CError_BufferAppendString(eb, "unsigned short"); + break; + case IT_INT: + CError_BufferAppendString(eb, "int"); + break; + case IT_UINT: + CError_BufferAppendString(eb, "unsigned int"); + break; + case IT_LONG: + CError_BufferAppendString(eb, "long"); + break; + case IT_ULONG: + CError_BufferAppendString(eb, "unsigned long"); + break; + case IT_LONGLONG: + CError_BufferAppendString(eb, "long long"); + break; + case IT_ULONGLONG: + CError_BufferAppendString(eb, "unsigned long long"); + break; + case IT_FLOAT: + CError_BufferAppendString(eb, "float"); + break; + case IT_SHORTDOUBLE: + CError_BufferAppendString(eb, "short double"); + break; + case IT_DOUBLE: + CError_BufferAppendString(eb, "double"); + break; + case IT_LONGDOUBLE: + CError_BufferAppendString(eb, "long double"); + break; + default: +#line 584 + CError_FATAL(); + } + break; + case TYPEENUM: + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendNameSpace(eb, TYPE_ENUM(ty)->nspace); + if (TYPE_ENUM(ty)->enumname) + CError_BufferAppendString(eb, TYPE_ENUM(ty)->enumname->name); + else + CError_BufferAppendString(eb, "{unnamed-enum}"); + break; + case TYPESTRUCT: + CError_BufferAppendQualifier(eb, qual); + switch (TYPE_STRUCT(ty)->stype) { + case STRUCT_TYPE_STRUCT: + CError_BufferAppendString(eb, "struct "); + break; + case STRUCT_TYPE_UNION: + CError_BufferAppendString(eb, "struct "); + break; + case STRUCT_TYPE_4: + case STRUCT_TYPE_5: + case STRUCT_TYPE_6: + case STRUCT_TYPE_7: + case STRUCT_TYPE_8: + case STRUCT_TYPE_9: + case STRUCT_TYPE_A: + case STRUCT_TYPE_B: + case STRUCT_TYPE_C: + case STRUCT_TYPE_D: + case STRUCT_TYPE_E: + break; + default: +#line 618 + CError_FATAL(); + } + if (TYPE_STRUCT(ty)->name) + CError_BufferAppendString(eb, TYPE_STRUCT(ty)->name->name); + break; + case TYPECLASS: + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendNameSpace(eb, TYPE_CLASS(ty)->nspace->parent); + if (TYPE_CLASS(ty)->classname) { + CError_BufferAppendString(eb, TYPE_CLASS(ty)->classname->name); + if (TYPE_CLASS(ty)->flags & CLASS_FLAGS_800) + CError_BufferAppendTemplArgs( + eb, + TEMPL_CLASS_INST(ty)->oargs ? TEMPL_CLASS_INST(ty)->oargs : TEMPL_CLASS_INST(ty)->inst_args + ); + } else { + CError_BufferAppendString(eb, "{unnamed-class}"); + } + break; + case TYPEPOINTER: + case TYPEMEMBERPOINTER: + scan = ty; + next_ptr: + switch (scan->type) { + case TYPEPOINTER: + scan = TYPE_POINTER(scan)->target; + goto next_ptr; + case TYPEMEMBERPOINTER: + scan = TYPE_MEMBER_POINTER(scan)->ty1; + goto next_ptr; + } + + CError_BufferAppendQualifier(eb, qual); + switch (scan->type) { + case TYPEFUNC: + if (TYPE_FUNC(scan)->flags & FUNC_FLAGS_PASCAL) + CError_BufferAppendString(eb, "pascal "); + CError_BufferAppendType(eb, TYPE_FUNC(scan)->functype, 0); + CError_BufferAppendString(eb, " ("); + CError_BufferAppendPType(eb, ty); + CError_BufferAppendChar(eb, ')'); + CError_BufferAppendFuncArgs(eb, TYPE_FUNC(scan), ty->type == TYPEMEMBERPOINTER); + break; + case TYPEARRAY: + scan2 = scan; + while (scan->type == TYPEARRAY) + scan = TYPE_POINTER(scan)->target; + CError_BufferAppendType(eb, scan, 0); + CError_BufferAppendString(eb, " ("); + CError_BufferAppendPType(eb, ty); + CError_BufferAppendChar(eb, ')'); + ty = scan2; + goto append_array_lengths; + default: + CError_BufferAppendType(eb, scan, 0); + CError_BufferAppendChar(eb, ' '); + CError_BufferAppendPType(eb, ty); + break; + } + break; + case TYPEFUNC: + if (TYPE_FUNC(ty)->flags & FUNC_FLAGS_PASCAL) + CError_BufferAppendString(eb, "pascal "); + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendType(eb, TYPE_FUNC(ty)->functype, 0); + CError_BufferAppendChar(eb, ' '); + CError_BufferAppendFuncArgs(eb, TYPE_FUNC(ty), 0); + break; + case TYPEARRAY: + CError_BufferAppendQualifier(eb, qual); + scan = ty; + while (scan->type == TYPEARRAY) + scan = TYPE_POINTER(scan)->target; + CError_BufferAppendType(eb, scan, 0); + append_array_lengths: + while (ty->type == TYPEARRAY) { + CError_BufferAppendChar(eb, '['); + if (ty->size && TYPE_POINTER(ty)->target->size) { + sprintf(buf, "%ld", ty->size / TYPE_POINTER(ty)->target->size); + CError_BufferAppendString(eb, buf); + } + CError_BufferAppendChar(eb, ']'); + ty = TYPE_POINTER(ty)->target; + } + break; + case TYPETEMPLATE: + CError_BufferAppendQualifier(eb, qual); + CError_BufferAppendTemplDepType(eb, TYPE_TEMPLATE(ty)); + break; + case TYPETEMPLDEPEXPR: + CError_BufferAppendString(eb, "T"); + break; + case TYPEBITFIELD: + sprintf(buf, "bitfield:%ld", TYPE_BITFIELD(ty)->unkB); + CError_BufferAppendString(eb, buf); + break; + default: +#line 752 + CError_FATAL(); + } +} + +char *CError_GetTypeName(Type *ty, UInt32 qual, Boolean useGlobalHeap) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_BufferAppendType(&eb, ty, qual); + CError_BufferTerminate(&eb); + + if (useGlobalHeap) + ptr = galloc(eb.size + 1); + else + ptr = lalloc(eb.size + 1); + + return strcpy(ptr, eb.start); +} + +void CError_AppendUnqualFunctionName(CErrorBuffer *eb, NameSpace *nspace, HashNameNode *name, TypeFunc *tfunc) { + Boolean flag = 0; + char *opname; + + if (nspace && nspace->theclass) { + if (name == constructor_name_node) { + CError_BufferAppendString(eb, nspace->theclass->classname->name); + flag = 1; + } else if (name == destructor_name_node) { + CError_BufferAppendChar(eb, '~'); + CError_BufferAppendString(eb, nspace->theclass->classname->name); + flag = 1; + } + } + + if (!flag) { + opname = CMangler_GetOperator(name); + if (!opname) { + if (tfunc && (tfunc->flags & FUNC_FLAGS_40)) { + CError_BufferAppendString(eb, "operator "); + CError_BufferAppendType(eb, tfunc->functype, tfunc->qual); + } else { + CError_BufferAppendString(eb, name->name); + } + } else { + CError_BufferAppendString(eb, opname); + } + } +} + +void CError_AppendFunctionName(CErrorBuffer *eb, NameSpace *nspace, HashNameNode *name, TemplArg *templargs, TypeFunc *tfunc) { + while (nspace->is_templ && nspace->parent) + nspace = nspace->parent; + + CError_BufferAppendNameSpace(eb, nspace); + CError_AppendUnqualFunctionName(eb, nspace, name, tfunc); + CError_BufferAppendTemplArgs(eb, templargs); + if (tfunc) { + if (!templargs && (tfunc->flags & FUNC_FLAGS_100000)) + CError_BufferAppendString(eb, "<...>"); + CError_BufferAppendFuncArgs(eb, tfunc, 0); + } else { + CError_BufferAppendString(eb, "()"); + } +} + +void CError_AppendObjectName(CErrorBuffer *eb, Object *obj) { + if (obj->type->type == TYPEFUNC) { + CError_AppendFunctionName(eb, obj->nspace, obj->name, obj->u.func.inst ? obj->u.func.inst->args : NULL, TYPE_FUNC(obj->type)); + } else { + CError_BufferAppendNameSpace(eb, obj->nspace); + CError_BufferAppendString(eb, obj->name->name); + } +} + +void CError_AppendMethodName(CErrorBuffer *eb, ObjCMethod *meth) { + ObjCMethodArg *arg; + + CError_BufferAppendChar(eb, meth->is_class_method ? '+' : '-'); + CError_BufferAppendChar(eb, '('); + CError_BufferAppendType(eb, meth->return_type, meth->return_qual); + CError_BufferAppendChar(eb, ')'); + for (arg = meth->selector_args; arg; arg = arg->next) { + if (arg->selector) + CError_BufferAppendString(eb, arg->selector->name); + if (arg->type) { + CError_BufferAppendString(eb, ":("); + CError_BufferAppendType(eb, arg->type, arg->qual); + CError_BufferAppendChar(eb, ')'); + } + } + if (meth->has_valist) + CError_BufferAppendString(eb, ",..."); +} + +char *CError_GetQualifiedName(NameSpace *nspace, HashNameNode *name) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_BufferAppendNameSpace(&eb, nspace); + CError_BufferAppendString(&eb, name->name); + CError_BufferTerminate(&eb); + + ptr = lalloc(eb.size + 1); + return strcpy(ptr, eb.start); +} + +char *CError_GetFunctionName(NameSpace *nspace, HashNameNode *name, TypeFunc *tfunc) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_AppendFunctionName(&eb, nspace, name, 0, tfunc); + CError_BufferTerminate(&eb); + + ptr = lalloc(eb.size + 1); + return strcpy(ptr, eb.start); +} + +char *CError_GetObjectName(Object *obj) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_AppendObjectName(&eb, obj); + CError_BufferTerminate(&eb); + + ptr = lalloc(eb.size + 1); + return strcpy(ptr, eb.start); +} + +char *CError_GetNameString(NameSpace *nspace, HashNameNode *operatorName) { + CErrorBuffer eb; + char buf[256]; + char *ptr; + char *opStr; + +#line 973 + CError_ASSERT(operatorName); + + opStr = CMangler_GetOperator(operatorName); + if (!opStr) + opStr = operatorName->name; + + if (nspace && nspace->name) { + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_BufferAppendNameSpace(&eb, nspace); + CError_BufferAppendString(&eb, opStr); + CError_BufferTerminate(&eb); + ptr = lalloc(eb.size + 1); + return strcpy(ptr, eb.start); + } else { + return opStr; + } +} + +void CError_ErrorMessage(int errTable, char *str, Boolean flag1, Boolean flag2) { + TStreamElement *token; + short tokensize; + CPrepFileInfo *tokenfile; + char buf[128]; + CWMessageRef myref; + CWMessageRef *ref; + unsigned char messagetype; + + if (CWDisplayLines(cparamblkptr->context, lines) != cwNoErr) + CError_UserBreak(); + + if (!in_assembler && !flag1 && cerror_lasterrorline == lines) { + if (cerror_errorcount++ >= 50) { + if (cerror_errorcount > 60) + longjmp(errorreturn, 1); + tk = lex(); + cerror_errorcount = 0; + if (tk == 0) { + CompilerGetCString(1, buf); + CWReportMessage(cparamblkptr->context, NULL, buf, NULL, messagetypeError, errTable); + longjmp(errorreturn, 1); + } + } + } else { + if (!flag2) { + cerror_lasterrorline = lines; + cerror_errorcount = 0; + } + if (copts.warningerrors) + flag2 = 0; + + if (cerror_token) + token = cerror_token; + else if (cerror_locktoken) + token = cerror_locktoken; + else + token = NULL; + //token = cerror_token ? cerror_token : cerror_locktoken ? cerror_locktoken : NULL; + if ((SInt32) token == -1) { + ref = NULL; + } else { + CPrep_GetTokenContext(token, &tokenfile, &myref.selectionoffset, &tokensize, &myref.linenumber, buf, &myref.tokenoffset, &myref.tokenlength, cerror_synchdata, &cerror_synchoffset); + myref.selectionlength = tokensize; + myref.sourcefile = tokenfile->textfile; + ref = &myref; + } + messagetype = flag2 ? messagetypeWarning : messagetypeError; + if (!flag2) { + anyerrors = 1; + fatalerrors = 1; + } + if (CWReportMessage(cparamblkptr->context, ref, str, buf, messagetype, errTable) != cwNoErr) + longjmp(errorreturn, 1); + } + + cerror_token = NULL; +} + +void CError_BufferAppendTemplateStack(CErrorBuffer *eb) { + TemplStack *stack[64]; + TemplStack *scan; + int index; + int indent; + int count; + + scan = ctempl_curinstance; + for (count = 0; scan && count < 64; count++) { + stack[count] = scan; + scan = scan->next; + } + + for (index = count - 1; index >= 0; index--) { + CError_BufferAppendChar(eb, '\n'); + for (indent = index; indent < count; indent++) + CError_BufferAppendChar(eb, ' '); + CError_BufferAppendString(eb, "(instantiating: '"); + if (stack[index]->is_func) + CError_AppendObjectName(eb, stack[index]->u.func); + else + CError_BufferAppendType(eb, (Type *) stack[index]->u.theclass, 0); + CError_BufferAppendString(eb, "')"); + } + + CError_BufferTerminate(eb); +} + +void CError_ErrorMessageVA(int code, const char *format, va_list list, Boolean flag1, Boolean flag2) { + // register allocation is fucked, matches otherwise + CErrorBuffer eb; + char buf[256]; + char unmangleBuf[256]; + SInt32 moddate; + Type *type; + UInt32 qual; + CError_BufferInit(&eb, buf, sizeof(buf)); + + do { + switch (format[0]) { + case 0: + break; + case '%': + switch (format[1]) { + case 'n': + MWUnmangle(va_arg(list, const char *), unmangleBuf, sizeof(unmangleBuf)); + CError_BufferAppendString(&eb, unmangleBuf); + format += 2; + continue; + case 'u': + CError_BufferAppendString(&eb, va_arg(list, const char *)); + format += 2; + continue; + case 'o': + CError_AppendObjectName(&eb, va_arg(list, Object *)); + format += 2; + continue; + case 'm': + CError_AppendMethodName(&eb, va_arg(list, ObjCMethod *)); + format += 2; + continue; + case 't': + type = va_arg(list, Type *); + qual = va_arg(list, UInt32); + CError_BufferAppendType(&eb, type, qual); + format += 2; + continue; + case '%': + CError_BufferAppendChar(&eb, '%'); + format += 2; + continue; + case 'i': + sprintf(unmangleBuf, "%ld", va_arg(list, SInt32)); + CError_BufferAppendString(&eb, unmangleBuf); + format += 2; + continue; + case 'f': + CError_BufferAppendString(&eb, CTool_GetPathName(va_arg(list, FSSpec *), &moddate)->name); + format += 2; + continue; + default: +#line 1174 + CError_FATAL(); + } + break; + default: + CError_BufferAppendChar(&eb, *(format++)); + continue; + } + break; + } while (1); + + CError_BufferAppendTemplateStack(&eb); + CError_ErrorMessage(code, eb.start, flag1, flag2); +} + +void CError_VAErrorMessage(int code, va_list list, Boolean flag1, Boolean flag2) { + char buf[256]; + + CError_GetErrorString(buf, code); + CError_ErrorMessageVA(code + 10000, buf, list, flag1, flag2); +} + +void CError_Error(int code, ...) { + va_list va; + + if (trychain) + longjmp(trychain->jmpbuf, 1); + + va_start(va, code); + CError_VAErrorMessage(code, va, 0, 0); + va_end(va); + + if (in_assembler && !preprocessing_only) + AssemblerError(); +} + +void CError_ErrorTerm(short code) { + CError_GetErrorString(string, code); + CError_ErrorMessage(code + 10000, string, 0, 0); + longjmp(errorreturn, 1); +} + +void CError_ErrorSkip(int code, ...) { + va_list va; + + if (trychain) + longjmp(trychain->jmpbuf, 1); + + va_start(va, code); + CError_VAErrorMessage(code, va, 0, 0); + va_end(va); + + if (tk != ';' && tk != ')' && tk != '}' && tk != ',' && tk != ']') + tk = lex(); +} + +void CError_ErrorFuncCall(short code, NameSpaceObjectList *args, ENodeList *argNodes) { + // does not match - one branch has loop weirdness + CErrorBuffer eb; + char buf[256]; + char *p; + ENodeList *argscan; + + if (trychain) + longjmp(trychain->jmpbuf, 1); + + CError_GetErrorString(string, code); + CError_BufferInit(&eb, buf, sizeof(buf)); + + while (args && args->object->otype != OT_OBJECT) + args = args->next; +#line 1268 + CError_ASSERT(args); + + p = string; + do { + switch (*p) { + case 0: + goto exit_main_loop; + case '*': + if (OBJECT(args->object)->type->type == TYPEFUNC) { + CError_AppendUnqualFunctionName( + &eb, + OBJECT(args->object)->nspace, + OBJECT(args->object)->name, + TYPE_FUNC(OBJECT(args->object)->type)); + if (TYPE_FUNC(OBJECT(args->object)->type)->flags & FUNC_FLAGS_METHOD) + if (TYPE_FUNC(OBJECT(args->object)->type)->flags & FUNC_FLAGS_1000) + if (TYPE_METHOD(OBJECT(args->object)->type)->theclass->flags & CLASS_FLAGS_20) + if (argNodes) + argNodes = argNodes->next; + } else { + CError_BufferAppendString(&eb, OBJECT(args->object)->name->name); + } + CError_BufferAppendChar(&eb, '('); + argscan = argNodes; + while (argscan) { + CError_BufferAppendType(&eb, argscan->node->rtype, argscan->node->flags & ENODE_FLAG_QUALS); + if ((argscan = argscan->next)) + CError_BufferAppendString(&eb, ", "); + } + CError_BufferAppendChar(&eb, ')'); + break; + default: + CError_BufferAppendChar(&eb, *p); + } + p++; + } while (1); + +exit_main_loop: + while (args) { + if (args->object->otype == OT_OBJECT) { + CError_BufferAppendChar(&eb, '\n'); + CError_BufferAppendChar(&eb, '\''); + CError_AppendObjectName(&eb, (Object *) args->object); + CError_BufferAppendChar(&eb, '\''); + } + args = args->next; + } + + CError_BufferAppendTemplateStack(&eb); + CError_ErrorMessage(10000 + code, eb.start, 0, 0); +} + +void CError_OverloadedFunctionError2(Object *obj, ObjectList *olst, ENodeList *argNodes) { + // not sure if the arg is actually ObjectList since it's never called lmao + NameSpaceObjectList first; + NameSpaceObjectList *current; + + first.object = (ObjBase *) obj; + current = &first; + while (olst) { + current->next = lalloc(sizeof(NameSpaceObjectList)); + current = current->next; + current->object = (ObjBase *) olst->object; + olst = olst->next; + } + current->next = NULL; + + CError_ErrorFuncCall(392, &first, argNodes); +} + +void CError_OverloadedFunctionError(Object *obj, ObjectList *olst) { + // not sure if this arg is ObjectList or NameSpaceObjectList + CErrorBuffer eb; + char buf[256]; + + if (trychain) + longjmp(trychain->jmpbuf, 1); + + CError_GetErrorString(string, 199); + CError_BufferInit(&eb, buf, sizeof(buf)); + CError_BufferAppendString(&eb, string); + + if (obj) { + CError_BufferAppendChar(&eb, '\n'); + CError_BufferAppendChar(&eb, '\''); + CError_AppendObjectName(&eb, obj); + CError_BufferAppendChar(&eb, '\''); + } + while (olst) { + CError_BufferAppendChar(&eb, '\n'); + CError_BufferAppendChar(&eb, '\''); + CError_AppendObjectName(&eb, olst->object); + CError_BufferAppendChar(&eb, '\''); + olst = olst->next; + } + CError_BufferAppendTemplateStack(&eb); + CError_ErrorMessage(10199, eb.start, 0, 0); +} + +void CError_AbstractClassError(TypeClass *tclass) { + int result = CClass_CheckPures(tclass); + if (!result) + CError_Error(372, tclass, 0); + else + CError_Error(194, result); +} + +void CError_Warning(int code, ...) { + va_list va; + if (trychain) + return; + + if (copts.supress_warnings) { + va_start(va, code); + } else { + va_start(va, code); + CError_VAErrorMessage(code, va, 0, 1); + } + va_end(va); +} + +void CError_BreakPoint(const char *a, const char *b) { + if (!a || !strcmp(a, b)) + CError_BreakPointcount++; +} + +void CError_Internal(char *filename, int line) { + char tmp[128]; + CompilerGetCString(5, tmp); + sprintf(string, tmp, filename, line); + CError_ErrorMessage(10001, string, 1, 0); + longjmp(errorreturn, 1); + CError_BreakPoint(0, 0); +} + +void CError_ExpressionTooComplex() { + CompilerGetCString(6, string); + CError_ErrorMessage(10002, string, 1, 0); + longjmp(errorreturn, 1); +} + +void CError_NoMem() { + cprep_nomem_exit = 1; + longjmp(errorreturn, 1); +} + +void CError_UserBreak() { + CompilerGetCString(8, string); + longjmp(errorreturn, 1); +} + +void CError_CannotOpen() { + CompilerGetCString(9, string); + CWReportMessage(cparamblkptr->context, NULL, string, NULL, messagetypeError, 0); + longjmp(errorreturn, 1); +} + +void CError_QualifierCheck(UInt32 qual) { + if (qual) { + Boolean anything = 0; + + if (qual & Q_CONST) { + CError_Error(CErrorStr313, "const"); + anything = 1; + } + if (qual & Q_VOLATILE) { + CError_Error(CErrorStr313, "volatile"); + anything = 1; + } + if (qual & Q_RESTRICT) { + CError_Error(CErrorStr313, "restrict"); + anything = 1; + } + if (qual & Q_ASM) { + CError_Error(CErrorStr313, "asm"); + anything = 1; + } + if (qual & Q_PASCAL) { + CError_Error(CErrorStr313, "pascal"); + anything = 1; + } + if (qual & Q_INLINE) { + CError_Error(CErrorStr313, "inline"); + anything = 1; + } + if (qual & Q_REFERENCE) { + CError_Error(CErrorStr313, "& reference type"); + anything = 1; + } + if (qual & Q_EXPLICIT) { + CError_Error(CErrorStr313, "explicit"); + anything = 1; + } + if (qual & Q_MUTABLE) { + CError_Error(CErrorStr313, "mutable"); + anything = 1; + } + if (qual & Q_VIRTUAL) { + CError_Error(CErrorStr313, "virtual"); + anything = 1; + } + if (qual & Q_FRIEND) { + CError_Error(CErrorStr313, "friend"); + anything = 1; + } + if (qual & Q_IN) { + CError_Error(CErrorStr313, "in"); + anything = 1; + } + if (qual & Q_OUT) { + CError_Error(CErrorStr313, "out"); + anything = 1; + } + if (qual & Q_INOUT) { + CError_Error(CErrorStr313, "inout"); + anything = 1; + } + if (qual & Q_BYCOPY) { + CError_Error(CErrorStr313, "bycopy"); + anything = 1; + } + if (qual & Q_BYREF) { + CError_Error(CErrorStr313, "byref"); + anything = 1; + } + if (qual & Q_ONEWAY) { + CError_Error(CErrorStr313, "oneway"); + anything = 1; + } + if (qual & Q_ALIGNED_MASK) { + CError_Error(CErrorStr313, "__attribute__((aligned(?)))"); + anything = 1; + } + + if (!anything) + CError_Error(CErrorStr176); + } +} diff --git a/compiler_and_linker/unsorted/CInt64.c b/compiler_and_linker/unsorted/CInt64.c new file mode 100644 index 0000000..ce2c45c --- /dev/null +++ b/compiler_and_linker/unsorted/CInt64.c @@ -0,0 +1,892 @@ +#include "compiler/CInt64.h" + +const CInt64 cint64_negone = {0xFFFFFFFF, 0xFFFFFFFF}; +const CInt64 cint64_zero = {0, 0}; +const CInt64 cint64_one = {0, 1}; +const CInt64 cint64_max = {0x7FFFFFFF, 0xFFFFFFFF}; +const CInt64 cint64_min = {0x80000000, 0}; + +#define SHIFT_LEFT_ONE(a, b) do { a <<= 1; if (b & 0x80000000) { a |= 1; } b <<= 1; } while(0) + +void CInt64_Init() { +} + +CInt64 CInt64_Not(CInt64 input) { + CInt64 output; + Boolean c; + + c = (input.hi == 0 && input.lo == 0); + CInt64_SetLong(&output, c); + + return output; +} + +CInt64 CInt64_Inv(CInt64 input) { + CInt64 output; + output.hi = ~input.hi; + output.lo = ~input.lo; + return output; +} + +CInt64 CInt64_Add(CInt64 lhs, CInt64 rhs) { + if (lhs.lo & 0x80000000) { + if (rhs.lo & 0x80000000) { + lhs.lo += rhs.lo; + lhs.hi += 1; + } else { + lhs.lo += rhs.lo; + if (!(lhs.lo & 0x80000000)) + lhs.hi += 1; + } + } else { + if (rhs.lo & 0x80000000) { + lhs.lo += rhs.lo; + if (!(lhs.lo & 0x80000000)) + lhs.hi += 1; + } else { + lhs.lo += rhs.lo; + } + } + lhs.hi += rhs.hi; + return lhs; +} + +CInt64 CInt64_Neg(CInt64 input) { + CInt64 result; + result = CInt64_Add(CInt64_Inv(input), cint64_one); + return result; +} + +CInt64 CInt64_Sub(CInt64 lhs, CInt64 rhs) { + lhs = CInt64_Add(lhs, CInt64_Neg(rhs)); + return lhs; +} + +CInt64 CInt64_MulU(CInt64 lhs, CInt64 rhs) { + CInt64 result; + CInt64 work1; + UInt32 aaaa; + UInt32 bbbb; + UInt32 cccc; + UInt32 dddd; + UInt32 eeee; + + aaaa = rhs.lo; + result.hi = result.lo = 0; + bbbb = lhs.lo; + cccc = rhs.hi; + dddd = rhs.lo; + + while (bbbb != 0) { + if (bbbb & 1) { + work1.hi = cccc; + work1.lo = dddd; + result = CInt64_Add(result, work1); + } + cccc <<= 1; + if (dddd & 0x80000000) + cccc |= 1; + dddd <<= 1; + bbbb >>= 1; + } + + eeee = lhs.hi; + while (eeee != 0 && aaaa != 0) { + if (eeee & 1) + result.hi += aaaa; + aaaa <<= 1; + eeee >>= 1; + } + + return result; +} + +CInt64 CInt64_Mul(CInt64 lhs, CInt64 rhs) { + if (CInt64_IsNegative(&rhs)) { + if (CInt64_IsNegative(&lhs)) { + return CInt64_MulU(CInt64_Neg(lhs), CInt64_Neg(rhs)); + } + return CInt64_Neg(CInt64_MulU(lhs, CInt64_Neg(rhs))); + } + if (CInt64_IsNegative(&lhs)) { + return CInt64_Neg(CInt64_MulU(CInt64_Neg(lhs), rhs)); + } + return CInt64_MulU(lhs, rhs); +} + +void CInt64_DivMod(const CInt64 *lhs, const CInt64 *rhs, CInt64 *pDiv, CInt64 *pMod) { + Boolean bad; + UInt32 workA; + UInt32 workB; + UInt32 leftA; + UInt32 leftB; + UInt32 rightA; + UInt32 rightB; + UInt32 outA; + UInt32 outB; + CInt64 work; + int counter; + + bad = (rhs->hi == 0) && (rhs->lo == 0); + if (!bad) { + workA = 0; + workB = 0; + leftA = lhs->hi; + leftB = lhs->lo; + rightA = rhs->hi; + rightB = rhs->lo; + outA = 0; + outB = 0; + counter = 0; + + do { + workA <<= 1; + if (workB & 0x80000000) + workA |= 1; + workB <<= 1; + if (leftA & 0x80000000) + workB |= 1; + leftA <<= 1; + if (leftB & 0x80000000) + leftA |= 1; + leftB <<= 1; + + outA <<= 1; + if (outB & 0x80000000) + outA |= 1; + outB <<= 1; + + if (workA <= rightA) { + if (workA != rightA) + continue; + if (workB < rightB) + continue; + } + + outB |= 1; + + work.hi = workA; + work.lo = workB; + work = CInt64_Sub(work, *rhs); + workA = work.hi; + workB = work.lo; + } while (++counter < 64); + + if (pDiv) { + pDiv->hi = outA; + pDiv->lo = outB; + } + if (pMod) { + pMod->hi = workA; + pMod->lo = workB; + } + } +} + +CInt64 CInt64_Div(CInt64 lhs, CInt64 rhs) { + CInt64 result; + if (CInt64_IsNegative(&rhs)) { + rhs = CInt64_Neg(rhs); + if (CInt64_IsNegative(&lhs)) { + lhs = CInt64_Neg(lhs); + CInt64_DivMod(&lhs, &rhs, &result, 0); + return result; + } else { + CInt64_DivMod(&lhs, &rhs, &result, 0); + return CInt64_Neg(result); + } + } else { + if (CInt64_IsNegative(&lhs)) { + lhs = CInt64_Neg(lhs); + CInt64_DivMod(&lhs, &rhs, &result, 0); + return CInt64_Neg(result); + } else { + CInt64_DivMod(&lhs, &rhs, &result, 0); + return result; + } + } +} + +CInt64 CInt64_DivU(CInt64 lhs, CInt64 rhs) { + CInt64 result; + CInt64_DivMod(&lhs, &rhs, &result, 0); + return result; +} + +CInt64 CInt64_Mod(CInt64 lhs, CInt64 rhs) { + CInt64 result; + if (CInt64_IsNegative(&lhs)) { + lhs = CInt64_Neg(lhs); + if (CInt64_IsNegative(&rhs)) + rhs = CInt64_Neg(rhs); + CInt64_DivMod(&lhs, &rhs, 0, &result); + return CInt64_Neg(result); + } else { + if (CInt64_IsNegative(&rhs)) + rhs = CInt64_Neg(rhs); + CInt64_DivMod(&lhs, &rhs, 0, &result); + return result; + } +} + +CInt64 CInt64_ModU(CInt64 lhs, CInt64 rhs) { + CInt64 result; + CInt64_DivMod(&lhs, &rhs, 0, &result); + return result; +} + +CInt64 CInt64_Shl(CInt64 lhs, CInt64 rhs) { + int counter; + UInt32 a; + UInt32 b; + + if (rhs.hi == 0 && rhs.lo < 64) { + a = lhs.hi; + b = lhs.lo; + for (counter = rhs.lo; counter != 0; --counter) { + a <<= 1; + if (b & 0x80000000) + a |= 1; + b <<= 1; + } + lhs.hi = a; + lhs.lo = b; + } else { + lhs.hi = 0; + lhs.lo = 0; + } + return lhs; +} + +CInt64 CInt64_Shr(CInt64 lhs, CInt64 rhs) { + int counter; + SInt32 a; + UInt32 b; + + if (rhs.hi == 0 && rhs.lo < 64) { + a = lhs.hi; + b = lhs.lo; + for (counter = rhs.lo; counter != 0; --counter) { + b >>= 1; + if (a & 1) + b |= 0x80000000; + a >>= 1; + } + lhs.hi = a; + lhs.lo = b; + } else { + if (lhs.hi & 0x80000000) { + lhs.hi = 0xFFFFFFFF; + lhs.lo = 0xFFFFFFFF; + } else { + lhs.hi = 0; + lhs.lo = 0; + } + } + return lhs; +} + +CInt64 CInt64_ShrU(CInt64 lhs, CInt64 rhs) { + int counter; + UInt32 a; + UInt32 b; + + if (rhs.hi == 0 && rhs.lo < 64) { + a = lhs.hi; + b = lhs.lo; + for (counter = rhs.lo; counter != 0; --counter) { + b >>= 1; + if (a & 1) + b |= 0x80000000; + a >>= 1; + } + lhs.hi = a; + lhs.lo = b; + } else { + lhs.hi = 0; + lhs.lo = 0; + } + return lhs; +} + +int CInt64_UnsignedCompare(const CInt64 *lhs, const CInt64 *rhs) { + if (lhs->hi == rhs->hi) { + if (lhs->lo < rhs->lo) + return -1; + else + return lhs->lo > rhs->lo; + } else { + return ((UInt32) lhs->hi < rhs->hi) ? -1 : 1; + } +} + +int CInt64_SignedCompare(const CInt64 *lhs, const CInt64 *rhs) { + CInt64 lhs_; + CInt64 rhs_; + + lhs_ = CInt64_Xor(*lhs, cint64_min); + rhs_ = CInt64_Xor(*rhs, cint64_min); + return CInt64_UnsignedCompare(&lhs_, &rhs_); +} + +Boolean CInt64_Less(CInt64 lhs, CInt64 rhs) { + return CInt64_SignedCompare(&lhs, &rhs) < 0; +} + +Boolean CInt64_LessU(CInt64 lhs, CInt64 rhs) { + return CInt64_UnsignedCompare(&lhs, &rhs) < 0; +} + +Boolean CInt64_Greater(CInt64 lhs, CInt64 rhs) { + return CInt64_SignedCompare(&lhs, &rhs) > 0; +} + +Boolean CInt64_GreaterU(CInt64 lhs, CInt64 rhs) { + return CInt64_UnsignedCompare(&lhs, &rhs) > 0; +} + +Boolean CInt64_LessEqual(CInt64 lhs, CInt64 rhs) { + return CInt64_SignedCompare(&lhs, &rhs) <= 0; +} + +Boolean CInt64_LessEqualU(CInt64 lhs, CInt64 rhs) { + return CInt64_UnsignedCompare(&lhs, &rhs) <= 0; +} + +Boolean CInt64_GreaterEqual(CInt64 lhs, CInt64 rhs) { + return CInt64_SignedCompare(&lhs, &rhs) >= 0; +} + +Boolean CInt64_GreaterEqualU(CInt64 lhs, CInt64 rhs) { + return CInt64_UnsignedCompare(&lhs, &rhs) >= 0; +} + +Boolean CInt64_Equal(CInt64 lhs, CInt64 rhs) { + return lhs.hi == rhs.hi && lhs.lo == rhs.lo; +} + +Boolean CInt64_NotEqual(CInt64 lhs, CInt64 rhs) { + return lhs.hi != rhs.hi || lhs.lo != rhs.lo; +} + +Boolean CInt64_IsInRange(CInt64 value, short len) { + CInt64 bound; + + if (value.hi & 0x80000000) { + switch (len) { + case 1: + bound.lo = 0xFFFFFF80; + bound.hi = 0xFFFFFFFF; + break; + case 2: + bound.lo = 0xFFFF8000; + bound.hi = 0xFFFFFFFF; + break; + case 4: + bound.lo = 0x80000000; + bound.hi = 0xFFFFFFFF; + break; + case 8: + return 1; + default: + return 0; + } + return CInt64_GreaterEqual(value, bound); + } else { + switch (len) { + case 1: + bound.lo = 0x7F; + bound.hi = 0; + break; + case 2: + bound.lo = 0x7FFF; + bound.hi = 0; + break; + case 4: + bound.lo = 0x7FFFFFFF; + bound.hi = 0; + break; + case 8: + return 1; + default: + return 0; + } + return CInt64_LessEqual(value, bound); + } +} + +Boolean CInt64_IsInURange(CInt64 value, short len) { + switch (len) { + case 1: + return value.hi == 0 && (value.lo & 0xFFFFFF00) == 0; + case 2: + return value.hi == 0 && (value.lo & 0xFFFF0000) == 0; + case 4: + return value.hi == 0; + case 8: + return 1; + default: + return 0; + } +} + +CInt64 CInt64_And(CInt64 lhs, CInt64 rhs) { + lhs.hi &= rhs.hi; + lhs.lo &= rhs.lo; + return lhs; +} + +CInt64 CInt64_Xor(CInt64 lhs, CInt64 rhs) { + lhs.hi ^= rhs.hi; + lhs.lo ^= rhs.lo; + return lhs; +} + +CInt64 CInt64_Or(CInt64 lhs, CInt64 rhs) { + lhs.hi |= rhs.hi; + lhs.lo |= rhs.lo; + return lhs; +} + +void CInt64_ConvertInt32(CInt64 *i) { + CInt64_Extend32(i); +} + +void CInt64_ConvertUInt32(CInt64 *i) { + CInt64_SetULong(i, (UInt32) i->lo); +} + +void CInt64_ConvertInt16(CInt64 *i) { + i->lo = (SInt32) i->lo; + CInt64_Extend32(i); +} + +void CInt64_ConvertUInt16(CInt64 *i) { + CInt64_SetULong(i, (UInt16) i->lo); +} + +void CInt64_ConvertInt8(CInt64 *i) { + i->lo = (SInt8) i->lo; + CInt64_Extend32(i); +} + +void CInt64_ConvertUInt8(CInt64 *i) { + CInt64_SetULong(i, (UInt8) i->lo); +} + +void CInt64_ConvertUFromLongDouble(CInt64 *pResult, double value) { + union { float f; UInt32 l; } cvt; + UInt32 a, b; + float threshold; + int bits; + + if (value <= 0.0) { + pResult->hi = 0; + pResult->lo = 0; + return; + } + + cvt.l = 0x5F800000; + if (value >= cvt.f) { + pResult->hi = 0xFFFFFFFF; + pResult->lo = 0xFFFFFFFF; + return; + } + + a = b = 0; + for (bits = 63; bits >= 0; bits--) { + a <<= 1; + if (b & 0x80000000) + a |= 1; + b <<= 1; + + if ((short) bits == 0) { + threshold = 1.0f; + } else { + cvt.l = (((short) bits + 127) & 255) << 23; + threshold = cvt.f; + } + + if (threshold <= value) { + b |= 1; + value -= threshold; + } + } + + pResult->hi = a; + pResult->lo = b; +} + +void CInt64_ConvertFromLongDouble(CInt64 *pResult, double value) { + if (value < 0.0) { + CInt64_ConvertUFromLongDouble(pResult, -value); + *pResult = CInt64_Neg(*pResult); + } else { + CInt64_ConvertUFromLongDouble(pResult, value); + } +} + +double CInt64_ConvertUToLongDouble(const CInt64 *value) { + Boolean bad; + UInt32 work; + int counter; + double result; + + bad = (value->hi == 0) && (value->lo == 0); + if (bad) { + return 0.0; + } else { + result = 0.0; + + work = value->hi; + if (work != 0) { + for (counter = 0; counter < 32; counter++) { + result += result; + if (work & 0x80000000) + result += 1.0; + work <<= 1; + } + } + + counter = 0; + work = value->lo; + for (; counter < 32; counter++) { + result += result; + if (work & 0x80000000) + result += 1.0; + work <<= 1; + } + + return result; + } +} + +double CInt64_ConvertToLongDouble(const CInt64 *value) { + CInt64 tmp; + if (value->hi & 0x80000000) { + tmp = CInt64_Neg(*value); + return -CInt64_ConvertUToLongDouble(&tmp); + } else { + return CInt64_ConvertUToLongDouble(value); + } +} + +char *CInt64_ScanOctString(CInt64 *pResult, char *str, Boolean *pFail) { + int ch; + CInt64 tmp; + UInt32 a; + UInt32 b; + + *pFail = 0; + pResult->hi = pResult->lo = 0; + + while ((ch = *str) >= '0' && *str <= '7') { + a = pResult->hi; + b = pResult->lo; + if (a & 0xE0000000) + *pFail = 1; + + SHIFT_LEFT_ONE(a, b); + SHIFT_LEFT_ONE(a, b); + SHIFT_LEFT_ONE(a, b); + + pResult->hi = a; + pResult->lo = b; + + CInt64_SetLong(&tmp, ch - '0'); + *pResult = CInt64_Add(*pResult, tmp); + ++str; + } + + return str; +} + +char *CInt64_ScanDecString(CInt64 *pResult, char *str, Boolean *pFail) { + int ch; + CInt64 tmp; + UInt32 a; + UInt32 b; + + *pFail = 0; + pResult->hi = pResult->lo = 0; + + while ((ch = *str) >= '0' && *str <= '9') { + a = pResult->hi; + b = pResult->lo; + if (a & 0xE0000000) + *pFail = 1; + + SHIFT_LEFT_ONE(a, b); + tmp.hi = a; + tmp.lo = b; + SHIFT_LEFT_ONE(a, b); + SHIFT_LEFT_ONE(a, b); + pResult->hi = a; + pResult->lo = b; + + if (CInt64_IsNegative(pResult)) { + *pResult = CInt64_Add(*pResult, tmp); + if (!CInt64_IsNegative(pResult)) + *pFail = 1; + } else { + *pResult = CInt64_Add(*pResult, tmp); + } + + CInt64_SetLong(&tmp, ch - '0'); + if (CInt64_IsNegative(pResult)) { + *pResult = CInt64_Add(*pResult, tmp); + if (!CInt64_IsNegative(pResult)) + *pFail = 1; + } else { + *pResult = CInt64_Add(*pResult, tmp); + } + + ++str; + } + + return str; +} + +char *CInt64_ScanHexString(CInt64 *pResult, char *str, Boolean *pFail) { + /* NOT MATCHING */ + int digit; + CInt64 tmp; + UInt32 a; + UInt32 b; + + *pFail = 0; + pResult->hi = pResult->lo = 0; + + for (;;) { + if ((digit = str[0]) >= '0' && digit <= '9') + digit = digit - '0'; + else if (digit >= 'A' && digit <= 'F') + digit = digit - 'A' + 10; + else if (digit >= 'a' && digit <= 'f') + digit = digit - 'a' + 10; + else + break; + + a = pResult->hi; + b = pResult->lo; + ++str; + + if (a & 0xF0000000) + *pFail = 1; + + SHIFT_LEFT_ONE(a, b); + SHIFT_LEFT_ONE(a, b); + SHIFT_LEFT_ONE(a, b); + SHIFT_LEFT_ONE(a, b); + + pResult->hi = a; + pResult->lo = b; + + CInt64_SetLong(&tmp, (char) digit); + *pResult = CInt64_Add(*pResult, tmp); + } + + return str; +} + +char *CInt64_ScanBinString(CInt64 *pResult, char *str, Boolean *pFail) { + char digit; + UInt32 a; + UInt32 b; + + *pFail = 0; + pResult->hi = pResult->lo = 0; + + for (;;) { + if (*str == '0') + digit = 0; + else if (*str == '1') + digit = 1; + else + break; + + a = pResult->hi; + b = pResult->lo; + ++str; + + if (a & 0x80000000) + *pFail = 1; + + SHIFT_LEFT_ONE(a, b); + + pResult->hi = a; + pResult->lo = b; + + if (digit == 1) + *pResult = CInt64_Add(*pResult, cint64_one); + } + + return str; +} + +char *CInt64_ScanAsmNumber(CInt64 *pResult, char *str, Boolean *pFail) { + Boolean isMaybeBin; + Boolean isOct; + Boolean isMaybeDec; + Boolean isBin; + char *p; + + isMaybeBin = 1; + isOct = *str == '0'; + isMaybeDec = 1; + isBin = 0; + p = str; + + for (;;) { + if (*p == 0) + break; + + if (strchr("01", p[0])) { + if (isBin) + isMaybeBin = 0; + } else if (strchr("bB", p[0])) { + isBin = 1; + isMaybeDec = 0; + isOct = 0; + } else if (strchr("234567", p[0])) { + isMaybeBin = 0; + } else if (strchr("89", p[0])) { + isOct = 0; + isMaybeBin = 0; + } else if (strchr("acdefACEDF", p[0])) { + isMaybeDec = 0; + isMaybeBin = 0; + } else { + break; + } + + ++p; + } + + if (isMaybeBin && isBin) { + return CInt64_ScanBinString(pResult, str, pFail) + 1; + } else if (p[0] == 'h' || p[0] == 'H') { + return CInt64_ScanHexString(pResult, str, pFail) + 1; + } else if (isOct) { + return CInt64_ScanOctString(pResult, str, pFail); + } else if (isMaybeDec) { + return CInt64_ScanDecString(pResult, str, pFail); + } else { + *pFail = 1; + return p; + } +} + +int CInt64_PrintDec(char *output, CInt64 value) { + int length; + CInt64 rem; + CInt64 divisor; + char buf[40]; + char *bufp; + + length = 0; + if (CInt64_IsNegative(&value)) { + value = CInt64_Neg(value); + *output = '-'; + length++; + output++; + } + + if (!CInt64_IsZero(&value)) { + divisor.lo = 10; + divisor.hi = 0; + + bufp = buf; + for (;;) { + rem = CInt64_ModU(value, divisor); + *(bufp++) = rem.lo + '0'; + value = CInt64_DivU(value, divisor); + if (CInt64_IsZero(&value) != 0) + break; + } + + while (--bufp >= buf) { + *(output++) = *bufp; + length++; + } + } else { + *(output++) = '0'; + length++; + } + + *output = 0; + return length; +} + +int CInt64_PrintHex(char *output, CInt64 value) { + int length; + CInt64 rem; + CInt64 shift; + CInt64 mask; + char buf[32]; + char *bufp; + + length = 0; + if (!CInt64_IsZero(&value)) { + shift.lo = 4; + shift.hi = 0; + mask.lo = 0xF; + mask.hi = 0; + + bufp = buf; + for (;;) { + rem = CInt64_And(value, mask); + if ((SInt32) rem.lo >= 10) + *(bufp++) = rem.lo + 'A'; + else + *(bufp++) = rem.lo + '0'; + value = CInt64_ShrU(value, shift); + if (CInt64_IsZero(&value) != 0) + break; + } + + while (--bufp >= buf) { + *(output++) = *bufp; + length++; + } + } else { + *(output++) = '0'; + length++; + } + + *output = 0; + return length; +} + +int CInt64_PrintBin(char *output, CInt64 value) { + int length; + CInt64 rem; + char buf[64]; + char *bufp; + + length = 0; + if (!CInt64_IsZero(&value)) { + bufp = buf; + for (;;) { + rem = CInt64_And(value, cint64_one); + if (CInt64_Equal(rem, cint64_one)) + *(bufp++) = '1'; + else + *(bufp++) = '0'; + value = CInt64_ShrU(value, cint64_one); + if (CInt64_IsZero(&value) != 0) + break; + } + + while (--bufp >= buf) { + *(output++) = *bufp; + length++; + } + } else { + *(output++) = '0'; + length++; + } + + *output = 0; + return length; +} diff --git a/compiler_and_linker/unsorted/CMachine.c b/compiler_and_linker/unsorted/CMachine.c new file mode 100644 index 0000000..f34ec88 --- /dev/null +++ b/compiler_and_linker/unsorted/CMachine.c @@ -0,0 +1,1499 @@ +#include "compiler.h" +#include "compiler/CError.h" +#include "compiler/CInt64.h" +#include "compiler/objects.h" +#include "compiler/types.h" + +TypeIntegral stbool = {TYPEINT, 0, IT_BOOL}; +TypeIntegral stchar = {TYPEINT, 1, IT_CHAR}; +TypeIntegral stsignedchar = {TYPEINT, 0, IT_SCHAR}; +TypeIntegral stunsignedchar = {TYPEINT, 0, IT_UCHAR}; +TypeIntegral stwchar = {TYPEINT, 4, IT_WCHAR_T}; +TypeIntegral stsignedshort = {TYPEINT, 2, IT_SHORT}; +TypeIntegral stunsignedshort = {TYPEINT, 2, IT_USHORT}; +TypeIntegral stsignedint = {TYPEINT, 4, IT_INT}; +TypeIntegral stunsignedint = {TYPEINT, 4, IT_UINT}; +TypeIntegral stsignedlong = {TYPEINT, 4, IT_LONG}; +TypeIntegral stunsignedlong = {TYPEINT, 4, IT_ULONG}; +TypeIntegral stsignedlonglong = {TYPEINT, 8, IT_LONGLONG}; +TypeIntegral stunsignedlonglong = {TYPEINT, 8, IT_ULONGLONG}; +TypeIntegral stfloat = {TYPEFLOAT, 4, IT_FLOAT}; +TypeIntegral stshortdouble = {TYPEINT, 8, IT_SHORTDOUBLE}; +TypeIntegral stdouble = {TYPEINT, 8, IT_DOUBLE}; +TypeIntegral stlongdouble = {TYPEINT, 8, IT_LONGDOUBLE}; + +static StructMember stVUC_unsignedchar15 = {NULL, (Type *) &stunsignedchar, NULL, 15, 0}; +static StructMember stVUC_unsignedchar14 = {&stVUC_unsignedchar15, (Type *) &stunsignedchar, NULL, 14, 0}; +static StructMember stVUC_unsignedchar13 = {&stVUC_unsignedchar14, (Type *) &stunsignedchar, NULL, 13, 0}; +static StructMember stVUC_unsignedchar12 = {&stVUC_unsignedchar13, (Type *) &stunsignedchar, NULL, 12, 0}; +static StructMember stVUC_unsignedchar11 = {&stVUC_unsignedchar12, (Type *) &stunsignedchar, NULL, 11, 0}; +static StructMember stVUC_unsignedchar10 = {&stVUC_unsignedchar11, (Type *) &stunsignedchar, NULL, 10, 0}; +static StructMember stVUC_unsignedchar9 = {&stVUC_unsignedchar10, (Type *) &stunsignedchar, NULL, 9, 0}; +static StructMember stVUC_unsignedchar8 = {&stVUC_unsignedchar9, (Type *) &stunsignedchar, NULL, 8, 0}; +static StructMember stVUC_unsignedchar7 = {&stVUC_unsignedchar7, (Type *) &stunsignedchar, NULL, 7, 0}; +static StructMember stVUC_unsignedchar6 = {&stVUC_unsignedchar7, (Type *) &stunsignedchar, NULL, 6, 0}; +static StructMember stVUC_unsignedchar5 = {&stVUC_unsignedchar6, (Type *) &stunsignedchar, NULL, 5, 0}; +static StructMember stVUC_unsignedchar4 = {&stVUC_unsignedchar5, (Type *) &stunsignedchar, NULL, 4, 0}; +static StructMember stVUC_unsignedchar3 = {&stVUC_unsignedchar4, (Type *) &stunsignedchar, NULL, 3, 0}; +static StructMember stVUC_unsignedchar2 = {&stVUC_unsignedchar3, (Type *) &stunsignedchar, NULL, 2, 0}; +static StructMember stVUC_unsignedchar1 = {&stVUC_unsignedchar2, (Type *) &stunsignedchar, NULL, 1, 0}; +static StructMember stVUC_unsignedchar0 = {&stVUC_unsignedchar1, (Type *) &stunsignedchar, NULL, 0, 0}; + +static StructMember stVSC_signedchar15 = {NULL, (Type *) &stsignedchar, NULL, 15, 0}; +static StructMember stVSC_signedchar14 = {&stVSC_signedchar15, (Type *) &stsignedchar, NULL, 14, 0}; +static StructMember stVSC_signedchar13 = {&stVSC_signedchar14, (Type *) &stsignedchar, NULL, 13, 0}; +static StructMember stVSC_signedchar12 = {&stVSC_signedchar13, (Type *) &stsignedchar, NULL, 12, 0}; +static StructMember stVSC_signedchar11 = {&stVSC_signedchar12, (Type *) &stsignedchar, NULL, 11, 0}; +static StructMember stVSC_signedchar10 = {&stVSC_signedchar11, (Type *) &stsignedchar, NULL, 10, 0}; +static StructMember stVSC_signedchar9 = {&stVSC_signedchar10, (Type *) &stsignedchar, NULL, 9, 0}; +static StructMember stVSC_signedchar8 = {&stVSC_signedchar9, (Type *) &stsignedchar, NULL, 8, 0}; +static StructMember stVSC_signedchar7 = {&stVSC_signedchar7, (Type *) &stsignedchar, NULL, 7, 0}; +static StructMember stVSC_signedchar6 = {&stVSC_signedchar7, (Type *) &stsignedchar, NULL, 6, 0}; +static StructMember stVSC_signedchar5 = {&stVSC_signedchar6, (Type *) &stsignedchar, NULL, 5, 0}; +static StructMember stVSC_signedchar4 = {&stVSC_signedchar5, (Type *) &stsignedchar, NULL, 4, 0}; +static StructMember stVSC_signedchar3 = {&stVSC_signedchar4, (Type *) &stsignedchar, NULL, 3, 0}; +static StructMember stVSC_signedchar2 = {&stVSC_signedchar3, (Type *) &stsignedchar, NULL, 2, 0}; +static StructMember stVSC_signedchar1 = {&stVSC_signedchar2, (Type *) &stsignedchar, NULL, 1, 0}; +static StructMember stVSC_signedchar0 = {&stVSC_signedchar1, (Type *) &stsignedchar, NULL, 0, 0}; + +static StructMember stVUS_unsignedshort7 = {NULL, (Type *) &stunsignedshort, NULL, 14, 0}; +static StructMember stVUS_unsignedshort6 = {&stVUS_unsignedshort7, (Type *) &stunsignedshort, NULL, 12, 0}; +static StructMember stVUS_unsignedshort5 = {&stVUS_unsignedshort7, (Type *) &stunsignedshort, NULL, 10, 0}; +static StructMember stVUS_unsignedshort4 = {&stVUS_unsignedshort5, (Type *) &stunsignedshort, NULL, 8, 0}; +static StructMember stVUS_unsignedshort3 = {&stVUS_unsignedshort4, (Type *) &stunsignedshort, NULL, 6, 0}; +static StructMember stVUS_unsignedshort2 = {&stVUS_unsignedshort3, (Type *) &stunsignedshort, NULL, 4, 0}; +static StructMember stVUS_unsignedshort1 = {&stVUS_unsignedshort2, (Type *) &stunsignedshort, NULL, 2, 0}; +static StructMember stVUS_unsignedshort0 = {&stVUS_unsignedshort1, (Type *) &stunsignedshort, NULL, 0, 0}; + +static StructMember stVSS_signedshort7 = {NULL, (Type *) &stsignedshort, NULL, 14, 0}; +static StructMember stVSS_signedshort6 = {&stVSS_signedshort7, (Type *) &stsignedshort, NULL, 12, 0}; +static StructMember stVSS_signedshort5 = {&stVSS_signedshort7, (Type *) &stsignedshort, NULL, 10, 0}; +static StructMember stVSS_signedshort4 = {&stVSS_signedshort5, (Type *) &stsignedshort, NULL, 8, 0}; +static StructMember stVSS_signedshort3 = {&stVSS_signedshort4, (Type *) &stsignedshort, NULL, 6, 0}; +static StructMember stVSS_signedshort2 = {&stVSS_signedshort3, (Type *) &stsignedshort, NULL, 4, 0}; +static StructMember stVSS_signedshort1 = {&stVSS_signedshort2, (Type *) &stsignedshort, NULL, 2, 0}; +static StructMember stVSS_signedshort0 = {&stVSS_signedshort1, (Type *) &stsignedshort, NULL, 0, 0}; + +static StructMember stVUL_unsignedlong3 = {NULL, (Type *) &stunsignedlong, NULL, 12, 0}; +static StructMember stVUL_unsignedlong2 = {&stVUL_unsignedlong3, (Type *) &stunsignedlong, NULL, 8, 0}; +static StructMember stVUL_unsignedlong1 = {&stVUL_unsignedlong2, (Type *) &stunsignedlong, NULL, 4, 0}; +static StructMember stVUL_unsignedlong0 = {&stVUL_unsignedlong1, (Type *) &stunsignedlong, NULL, 0, 0}; + +static StructMember stVSL_signedlong3 = {NULL, (Type *) &stsignedlong, NULL, 12, 0}; +static StructMember stVSL_signedlong2 = {&stVSL_signedlong3, (Type *) &stsignedlong, NULL, 8, 0}; +static StructMember stVSL_signedlong1 = {&stVSL_signedlong2, (Type *) &stsignedlong, NULL, 4, 0}; +static StructMember stVSL_signedlong0 = {&stVSL_signedlong1, (Type *) &stsignedlong, NULL, 0, 0}; + +static StructMember stVF_float3 = {NULL, (Type *) &stfloat, NULL, 12, 0}; +static StructMember stVF_float2 = {&stVF_float3, (Type *) &stfloat, NULL, 8, 0}; +static StructMember stVF_float1 = {&stVF_float2, (Type *) &stfloat, NULL, 4, 0}; +static StructMember stVF_float0 = {&stVF_float1, (Type *) &stfloat, NULL, 0, 0}; + +TypeStruct stvectorunsignedchar = {TYPESTRUCT, 16, NULL, &stVUC_unsignedchar0, STRUCT_TYPE_4, 16}; +TypeStruct stvectorsignedchar = {TYPESTRUCT, 16, NULL, &stVSC_signedchar0, STRUCT_TYPE_5, 16}; +TypeStruct stvectorboolchar = {TYPESTRUCT, 16, NULL, &stVSC_signedchar0, STRUCT_TYPE_6, 16}; + +TypeStruct stvectorunsignedshort = {TYPESTRUCT, 16, NULL, &stVUS_unsignedshort0, STRUCT_TYPE_7, 16}; +TypeStruct stvectorsignedshort = {TYPESTRUCT, 16, NULL, &stVSS_signedshort0, STRUCT_TYPE_8, 16}; +TypeStruct stvectorboolshort = {TYPESTRUCT, 16, NULL, &stVSS_signedshort0, STRUCT_TYPE_9, 16}; + +TypeStruct stvectorunsignedlong = {TYPESTRUCT, 16, NULL, &stVUL_unsignedlong0, STRUCT_TYPE_A, 16}; +TypeStruct stvectorsignedlong = {TYPESTRUCT, 16, NULL, &stVSL_signedlong0, STRUCT_TYPE_B, 16}; +TypeStruct stvectorboollong = {TYPESTRUCT, 16, NULL, &stVSL_signedlong0, STRUCT_TYPE_C, 16}; + +TypeStruct stvectorfloat = {TYPESTRUCT, 16, NULL, &stVF_float0, STRUCT_TYPE_D, 16}; + +TypeStruct stvectorpixel = {TYPESTRUCT, 16, NULL, &stVUS_unsignedshort0, STRUCT_TYPE_E, 16}; + +TypeStruct stvector = {TYPESTRUCT, 16, NULL, NULL, STRUCT_TYPE_A, 16}; + +static SInt32 cmach_structoffset; +static UInt8 cmach_structalign; +static short cmach_curbfsize; +static short cmach_curbfbasesize; +static int cmach_curbfoffset; + +static short cmach_packsize[] = { + 1, 2, 4, 8, 16 +}; + +// forward declarations +static SInt16 CMach_GetQualifiedTypeAlign(Type *type, Boolean flag); +static SInt16 CMach_GetMemberAlignment(Type *type, SInt32 align, Boolean flag); + +void CMach_Configure() { +} + +SInt32 CMach_GetQUALalign(UInt32 qual) { + SInt32 result = 0; + SInt32 chk; + + if ((chk = (qual & Q_ALIGNED_MASK))) { + if (chk == Q_ALIGNED_1) + result = 1; + else if (chk == Q_ALIGNED_2) + result = 2; + else if (chk == Q_ALIGNED_4) + result = 4; + else if (chk == Q_ALIGNED_8) + result = 8; + else if (chk == Q_ALIGNED_16) + result = 16; + else if (chk == Q_ALIGNED_32) + result = 32; + else if (chk == Q_ALIGNED_64) + result = 64; + else if (chk == Q_ALIGNED_128) + result = 128; + else if (chk == Q_ALIGNED_256) + result = 256; + else if (chk == Q_ALIGNED_512) + result = 512; + else if (chk == Q_ALIGNED_1024) + result = 1024; + else if (chk == Q_ALIGNED_2048) + result = 2048; + else if (chk == Q_ALIGNED_4096) + result = 4096; + else if (chk == Q_ALIGNED_8192) + result = 8192; + else { +#line 226 + CError_FATAL(); + } + } + + return result; +} + +SInt32 CMach_ArgumentAlignment(Type *type) { + // does not match - registers + UInt8 save_align_mode; + UInt8 save_oldalignment; + SInt32 align; + + save_align_mode = copts.align_mode; + save_oldalignment = copts.oldalignment; + copts.align_mode = AlignMode2_PPC; + copts.oldalignment = 0; + align = CMach_GetQualifiedTypeAlign(type, 0); + copts.align_mode = save_align_mode; + copts.oldalignment = save_oldalignment; + + if (type->type == TYPESTRUCT && !TYPE_STRUCT(type)->members && TYPE_STRUCT(type)->align > align) + align = TYPE_STRUCT(type)->align; + + return align; +} + +SInt32 CMach_AllocationAlignment(Type *type, UInt32 qual) { + SInt32 align; + SInt32 qualalign; + SInt32 argalign; + SInt32 anotheralign; + + qualalign = CMach_GetQUALalign(qual); + align = CMach_GetQualifiedTypeAlign(type, 1); + if (qualalign > align) + align = qualalign; + argalign = CMach_ArgumentAlignment(type); + if (argalign > align) + align = argalign; + + switch (type->type) { + case TYPEVOID: + case TYPEMEMBERPOINTER: + case TYPEPOINTER: + anotheralign = 4; + break; + default: + anotheralign = 1; + } + if (anotheralign > align) + align = anotheralign; + + if (copts.optimizationlevel > 0) { + if (type->type == TYPEARRAY || (type->type == TYPESTRUCT && (TYPE_STRUCT(type)->stype < STRUCT_TYPE_4 || TYPE_STRUCT(type)->stype > STRUCT_TYPE_E)) || type->type == TYPECLASS || (type->type == TYPEMEMBERPOINTER && (UInt32) type->size == 12)) { + return (copts.some_alignment > align) ? copts.some_alignment : align; + } + } + + return align; +} + +CInt64 CMach_CalcIntDiadic(Type *type, CInt64 left, short op, CInt64 right) { + if (is_unsigned(type)) { + switch (type->size) { + case 1: + CInt64_ConvertUInt8(&left); + CInt64_ConvertUInt8(&right); + break; + case 2: + CInt64_ConvertUInt16(&left); + CInt64_ConvertUInt16(&right); + break; + case 4: + CInt64_ConvertUInt32(&left); + CInt64_ConvertUInt32(&right); + break; + case 8: + break; + default: +#line 327 + CError_FATAL(); + } + + switch (op) { + case '*': + left = CInt64_MulU(left, right); + break; + case '/': + if (CInt64_IsZero(&right)) + CError_Warning(139); + else + left = CInt64_DivU(left, right); + break; + case '%': + if (CInt64_IsZero(&right)) + CError_Warning(139); + else + left = CInt64_ModU(left, right); + break; + case '+': + left = CInt64_Add(left, right); + break; + case '-': + left = CInt64_Sub(left, right); + break; + case TK_SHL: + left = CInt64_Shl(left, right); + break; + case TK_SHR: + left = CInt64_ShrU(left, right); + break; + case '<': + CInt64_SetLong(&left, CInt64_LessU(left, right)); + break; + case '>': + CInt64_SetLong(&left, CInt64_GreaterU(left, right)); + break; + case TK_LESS_EQUAL: + CInt64_SetLong(&left, CInt64_LessEqualU(left, right)); + break; + case TK_GREATER_EQUAL: + CInt64_SetLong(&left, CInt64_GreaterEqualU(left, right)); + break; + case TK_LOGICAL_EQ: + CInt64_SetLong(&left, CInt64_Equal(left, right)); + break; + case TK_LOGICAL_NE: + CInt64_SetLong(&left, CInt64_NotEqual(left, right)); + break; + case '&': + left = CInt64_And(left, right); + break; + case '^': + left = CInt64_Xor(left, right); + break; + case '|': + left = CInt64_Or(left, right); + break; + case TK_LOGICAL_AND: + CInt64_SetLong(&left, (CInt64_IsZero(&left) == 0 && CInt64_IsZero(&right) == 0)); + break; + case TK_LOGICAL_OR: + CInt64_SetLong(&left, (CInt64_IsZero(&left) == 0 || CInt64_IsZero(&right) == 0)); + break; + default: + CError_Error(120); + } + + switch (type->size) { + case 1: + CInt64_ConvertUInt8(&left); + break; + case 2: + CInt64_ConvertUInt16(&left); + break; + case 4: + CInt64_ConvertUInt32(&left); + break; + case 8: + break; + } + } else { + switch (type->size) { + case 1: + CInt64_ConvertInt8(&left); + CInt64_ConvertInt8(&right); + break; + case 2: + CInt64_ConvertInt16(&left); + CInt64_ConvertInt16(&right); + break; + case 4: + CInt64_ConvertInt32(&left); + CInt64_ConvertInt32(&right); + break; + case 8: + break; + default: +#line 389 + CError_FATAL(); + } + + switch (op) { + case '*': + left = CInt64_Mul(left, right); + break; + case '/': + if (CInt64_IsZero(&right)) + CError_Warning(139); + else + left = CInt64_Div(left, right); + break; + case '%': + if (CInt64_IsZero(&right)) + CError_Warning(139); + else + left = CInt64_Mod(left, right); + break; + case '+': + left = CInt64_Add(left, right); + break; + case '-': + left = CInt64_Sub(left, right); + break; + case TK_SHL: + left = CInt64_Shl(left, right); + break; + case TK_SHR: + left = CInt64_Shr(left, right); + break; + case '<': + CInt64_SetLong(&left, CInt64_Less(left, right)); + break; + case '>': + CInt64_SetLong(&left, CInt64_Greater(left, right)); + break; + case TK_LESS_EQUAL: + CInt64_SetLong(&left, CInt64_LessEqual(left, right)); + break; + case TK_GREATER_EQUAL: + CInt64_SetLong(&left, CInt64_GreaterEqual(left, right)); + break; + case TK_LOGICAL_EQ: + CInt64_SetLong(&left, CInt64_Equal(left, right)); + break; + case TK_LOGICAL_NE: + CInt64_SetLong(&left, CInt64_NotEqual(left, right)); + break; + case '&': + left = CInt64_And(left, right); + break; + case '^': + left = CInt64_Xor(left, right); + break; + case '|': + left = CInt64_Or(left, right); + break; + case TK_LOGICAL_AND: + CInt64_SetLong(&left, (CInt64_IsZero(&left) == 0 && CInt64_IsZero(&right) == 0)); + break; + case TK_LOGICAL_OR: + CInt64_SetLong(&left, (CInt64_IsZero(&left) == 0 || CInt64_IsZero(&right) == 0)); + break; + default: + CError_Error(120); + } + + switch (type->size) { + case 1: + CInt64_ConvertInt8(&left); + break; + case 2: + CInt64_ConvertInt16(&left); + break; + case 4: + CInt64_ConvertInt32(&left); + break; + case 8: + break; + } + } + + return left; +} + +CInt64 CMach_CalcIntMonadic(Type *type, short op, CInt64 val) { + if (is_unsigned(type)) { + switch (type->size) { + case 1: + CInt64_ConvertUInt8(&val); + break; + case 2: + CInt64_ConvertUInt16(&val); + break; + case 4: + CInt64_ConvertUInt32(&val); + break; + case 8: + break; + default: +#line 448 + CError_FATAL(); + } + + switch (op) { + case '-': + val = CInt64_Neg(val); + break; + case '~': + val = CInt64_Inv(val); + break; + case '!': + val = CInt64_Not(val); + break; + default: + CError_Error(120); + } + + switch (type->size) { + case 1: + CInt64_ConvertUInt8(&val); + break; + case 2: + CInt64_ConvertUInt16(&val); + break; + case 4: + CInt64_ConvertUInt32(&val); + break; + case 8: + break; + } + } else { + switch (type->size) { + case 1: + CInt64_ConvertInt8(&val); + break; + case 2: + CInt64_ConvertInt16(&val); + break; + case 4: + CInt64_ConvertInt32(&val); + break; + case 8: + break; + default: +#line 478 + CError_FATAL(); + } + + switch (op) { + case '-': + val = CInt64_Neg(val); + break; + case '~': + val = CInt64_Inv(val); + break; + case '!': + val = CInt64_Not(val); + break; + default: + CError_Error(120); + } + + switch (type->size) { + case 1: + CInt64_ConvertInt8(&val); + break; + case 2: + CInt64_ConvertInt16(&val); + break; + case 4: + CInt64_ConvertInt32(&val); + break; + case 8: + break; + } + } + + return val; +} + +CInt64 CMach_CalcIntConvertFromFloat(Type *type, Float fval) { + CInt64 result; + + if ((type->type == TYPEINT || type->type == TYPEENUM) && (type->size == 8)) { + if (is_unsigned(type)) + CInt64_ConvertUFromLongDouble(&result, fval.value); + else + CInt64_ConvertFromLongDouble(&result, fval.value); + } else { + if (is_unsigned(type)) + CInt64_SetULong(&result, fval.value); + else + CInt64_SetLong(&result, fval.value); + } + + return result; +} + +void CMach_InitIntMem(Type *type, CInt64 val, void *mem) { + UInt32 lg; + UInt16 sh; + UInt8 ch; + + switch (type->type) { + case TYPEINT: + switch (type->size) { + case 1: + ch = (UInt8) val.lo; + memcpy(mem, &ch, 1); + break; + case 2: + sh = (UInt16) val.lo; + memcpy(mem, &sh, 2); + break; + case 4: + lg = (UInt32) val.lo; + memcpy(mem, &lg, 4); + break; + case 8: + CTool_EndianConvertWord64(val, mem); + break; + default: +#line 566 + CError_FATAL(); + } + break; + default: +#line 570 + CError_FATAL(); + } +} + +void CMach_InitVectorMem(Type *type, MWVector128 val, void *mem) { + unsigned char uc[16]; + unsigned short us[8]; + unsigned int ul[4]; + float f[4]; + int i; + + switch (type->type) { + case TYPESTRUCT: + switch (TYPE_STRUCT(type)->stype) { + case STRUCT_TYPE_4: + case STRUCT_TYPE_5: + case STRUCT_TYPE_6: + for (i = 0; i < 16; i++) + uc[i] = val.uc[i]; + memcpy(mem, uc, 16); + break; + case STRUCT_TYPE_7: + case STRUCT_TYPE_8: + case STRUCT_TYPE_9: + case STRUCT_TYPE_E: + for (i = 0; i < 8; i++) + us[i] = val.us[i]; + memcpy(mem, us, 16); + break; + case STRUCT_TYPE_A: + case STRUCT_TYPE_B: + case STRUCT_TYPE_C: + for (i = 0; i < 4; i++) + ul[i] = val.ul[i]; + memcpy(mem, ul, 16); + break; + case STRUCT_TYPE_D: + for (i = 0; i < 4; i++) + f[i] = val.f[i]; + memcpy(mem, f, 16); + break; + default: +#line 655 + CError_FATAL(); + } + break; + default: +#line 659 + CError_FATAL(); + } +} + +Float CMach_CalcFloatDiadic(Type *type, Float left, short op, Float right) { + switch (op) { + case '+': + left.value += right.value; + break; + case '-': + left.value -= right.value; + break; + case '*': + left.value *= right.value; + break; + case '/': + left.value /= right.value; + break; + default: +#line 679 + CError_FATAL(); + } + + return CMach_CalcFloatConvert(type, left); +} + +Float CMach_CalcFloatMonadic(Type *type, short op, Float fval) { + if (op != '-') +#line 692 + CError_FATAL(); + + fval.value = -fval.value; + return CMach_CalcFloatConvert(type, fval); +} + +Boolean CMach_CalcFloatDiadicBool(Type *type, Float left, short op, Float right) { + switch (op) { + case TK_LOGICAL_EQ: + return left.value == right.value; + case TK_LOGICAL_NE: + return left.value != right.value; + case TK_LESS_EQUAL: + return left.value <= right.value; + case TK_GREATER_EQUAL: + return left.value >= right.value; + case '>': + return left.value > right.value; + case '<': + return left.value < right.value; + default: +#line 714 + CError_FATAL(); + return 0; + } +} + +Boolean CMach_CalcVectorDiadicBool(Type *type, MWVector128 *left, short op, MWVector128 *right) { + switch (op) { + case TK_LOGICAL_EQ: + return (left->ul[0] == right->ul[0]) && (left->ul[1] == right->ul[1]) && (left->ul[2] == right->ul[2]) && (left->ul[3] == right->ul[3]); + case TK_LOGICAL_NE: + return (left->ul[0] != right->ul[0]) && (left->ul[1] != right->ul[1]) && (left->ul[2] != right->ul[2]) && (left->ul[3] != right->ul[3]); + default: +#line 740 + CError_FATAL(); + return 0; + } +} + +char *CMach_FloatScan(char *input, Float *result, Boolean *fail) { + double resultval; + char *outpos; + + if (!(outpos = ScanFloat(input, &resultval, fail))) + CError_ErrorTerm(154); + + if (*fail) + result->value = 0.0; + else + result->value = resultval; + + return outpos; +} + +Float CMach_CalcFloatConvertFromInt(Type *type, CInt64 val) { + Float result; + + if ((type->type == TYPEINT || type->type == TYPEENUM) && (type->size == 8)) { + if (is_unsigned(type)) + result.value = CInt64_ConvertUToLongDouble(&val); + else + result.value = CInt64_ConvertToLongDouble(&val); + } else { + if (is_unsigned(type)) + result.value = val.lo; + else + result.value = (SInt32) val.lo; + } + + return result; +} + +Float CMach_CalcFloatConvert(Type *type, Float fval) { + switch (type->size) { + case 4: + fval.value = (float) fval.value; + break; + case 8: + fval.value = (double) fval.value; + break; + case 10: + case 12: + break; + default: +#line 801 + CError_FATAL(); + } + return fval; +} + +Boolean CMach_FloatIsZero(Float fval) { + return fval.value == 0.0; +} + +Boolean CMach_FloatIsOne(Float fval) { + return fval.value == 1.0; +} + +Boolean CMach_FloatIsNegOne(Float fval) { + return fval.value == -1.0; +} + +void CMach_InitFloatMem(Type *type, Float val, void *mem) { + float f; + double d; + + if (type->type == TYPEFLOAT) { + switch (type->size) { + case 4: + f = val.value; + memcpy(mem, &f, 4); + return; + case 8: + d = val.value; + memcpy(mem, &d, 8); + return; + } + } + +#line 866 + CError_FATAL(); +} + +void CMach_PrintFloat(char *buf, Float val) { + double f; + CMach_InitFloatMem((Type *) &stshortdouble, val, &f); + sprintf(buf, "%g", f); +} + +void CMach_PragmaParams() { + if (copts.warn_illpragma) + CError_Warning(186, 0); + + while (notendofline()) + lex(); +} + +void CMach_AdjustFuntionArgs() { + // not called so we will never know what the args should have been :( +} + +static SInt32 CMach_GetPPCTypeAlign(Type *type, Boolean flag1, Boolean flag2) { + ClassList *base; + ObjMemberVar *ivar; + StructMember *member; + SInt32 best; + SInt32 ivarAlign; + SInt32 qualAlign; + + SInt32 align = CMach_GetQualifiedTypeAlign(type, flag2); + if (align <= 8) { + while (type->type == TYPEARRAY) + type = TYPE_POINTER(type)->target; + + if (flag1) { + if (type->type == TYPEFLOAT && type->size > 4 && align < 8) + return 8; + } else if (align == 8) { + if (type->type == TYPECLASS) { + best = 4; + for (base = TYPE_CLASS(type)->bases; base; base = base->next) { + if (base->base->align > best) + best = base->base->align; + } + for (ivar = TYPE_CLASS(type)->ivars; ivar; ivar = ivar->next) { + ivarAlign = CMach_GetPPCTypeAlign(ivar->type, 0, flag2); + if (ivarAlign > best) + best = ivarAlign; + if (flag2) { + qualAlign = CMach_GetQUALalign(ivar->qual); + if (qualAlign > best) + best = qualAlign; + } + } + return best; + } + if (type->type == TYPESTRUCT) { + best = 4; + for (member = TYPE_STRUCT(type)->members; member; member = member->next) { + ivarAlign = CMach_GetPPCTypeAlign(member->type, 0, flag2); + if (ivarAlign > best) + best = ivarAlign; + if (flag2) { + qualAlign = CMach_GetQUALalign(member->qual); + if (qualAlign > best) + best = qualAlign; + } + } + return best; + } + } + } + + return align; +} + +static SInt16 CMach_GetQualifiedStructAlign(TypeStruct *tstruct, Boolean flag) { + StructMember *member; + SInt32 best; + SInt32 align; + Boolean isFirst; + + // very close to matching but tstruct->stype gets cached when it should not be + if (tstruct->stype >= STRUCT_TYPE_4 && tstruct->stype <= STRUCT_TYPE_E) { + return 16; + } else { + + switch (copts.align_mode) { + case AlignMode3_1Byte: + case AlignMode8: + return 1; + case AlignMode0_Mac68k: + return 2; + case AlignMode1_Mac68k4byte: + return (tstruct->size <= 2) ? 2 : 4; + } + + if (tstruct->size <= 1) + return 1; + best = 1; + switch (copts.align_mode) { + default: +#line 1026 + CError_FATAL(); + case AlignMode4_2Byte: + case AlignMode5_4Byte: + case AlignMode6_8Byte: + case AlignMode7_16Byte: + for (member = tstruct->members; member; member = member->next) { + align = CMach_GetQualifiedTypeAlign(member->type, flag); + if (align > best) + best = align; + if (flag) { + align = CMach_GetQUALalign(member->qual); + if (align > best) + best = align; + } + } + return best; + case AlignMode2_PPC: + if (copts.oldalignment) { + for (member = tstruct->members; member; member = member->next) { + align = CMach_GetQualifiedTypeAlign(member->type, flag); + if (align > best) + best = align; + if (flag) { + align = CMach_GetQUALalign(member->qual); + if (align > best) + best = align; + } + } + } else if (tstruct->stype == STRUCT_TYPE_UNION) { + for (member = tstruct->members; member; member = member->next) { + align = CMach_GetPPCTypeAlign(member->type, 1, flag); + if (align > best) + best = align; + if (flag) { + align = CMach_GetQUALalign(member->qual); + if (align > best) + best = align; + } + } + } else { + isFirst = 1; + for (member = tstruct->members; member; member = member->next) { + align = CMach_GetPPCTypeAlign(member->type, isFirst || (best >= 8), flag); + if (align > best) + best = align; + if (flag) { + align = CMach_GetQUALalign(member->qual); + if (align > best) + best = align; + } + isFirst = 0; + } + } + return best; + } + } +} + +SInt16 CMach_GetStructAlign(TypeStruct *tstruct) { + return CMach_GetQualifiedStructAlign(tstruct, 1); +} + +static SInt16 CMach_GetQualifiedClassAlign(TypeClass *tclass, Boolean flag) { + ClassList *base; + ObjMemberVar *ivar; + SInt32 best; + SInt32 align; + Boolean isFirst; + + switch (copts.align_mode) { + case AlignMode3_1Byte: + case AlignMode8: + return 1; + case AlignMode0_Mac68k: + return 2; + case AlignMode1_Mac68k4byte: + return (tclass->size <= 2) ? 2 : 4; + } + if (tclass->size <= 1) + return 1; + best = 1; + switch (copts.align_mode) { + default: +#line 1149 + CError_FATAL(); + case AlignMode4_2Byte: + case AlignMode5_4Byte: + case AlignMode6_8Byte: + case AlignMode7_16Byte: + for (base = tclass->bases; base; base = base->next) { + if ((align = base->base->align) > best) + best = align; + } + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + align = CMach_GetMemberAlignment(ivar->type, flag ? CMach_GetQUALalign(ivar->qual) : 0, flag); + if (align > best) + best = align; + } + return best; + case AlignMode2_PPC: + best = 1; + if (copts.oldalignment) { + for (base = tclass->bases; base; base = base->next) { + if ((align = base->base->align) > best) + best = align; + } + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + align = CMach_GetMemberAlignment(ivar->type, flag ? CMach_GetQUALalign(ivar->qual) : 0, flag); + if (align > best) + best = align; + } + } else { + isFirst = 1; + for (base = tclass->bases; base; base = base->next) { + if ((align = base->base->align) > best) + best = align; + isFirst = 0; + } + if (tclass->mode == 1) { + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + align = CMach_GetPPCTypeAlign(ivar->type, 1, flag); + if (align > best) + best = align; + if (flag) { + align = CMach_GetQUALalign(ivar->qual); + if (align > best) + best = align; + } + } + } else { + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + if (ivar->offset && align != 8) + isFirst = 0; + align = CMach_GetPPCTypeAlign(ivar->type, isFirst || (best >= 8), flag); + if (align > best) + best = align; + if (flag) { + align = CMach_GetQUALalign(ivar->qual); + if (align > best) + best = align; + } + } + } + } + return best; + } +} + +SInt16 CMach_GetClassAlign(TypeClass *tclass) { + return CMach_GetQualifiedClassAlign(tclass, 1); +} + +static SInt16 CMach_GetWinTypeAlign(Type *type) { + int packoffs = copts.align_mode - 3; + SInt32 align = cmach_packsize[packoffs]; + if (type->size < align) + align = type->size; + return align; +} + +static SInt16 CMach_GetWinMinimizeAlign(SInt16 align) { + int packoffs = copts.align_mode - 3; + SInt16 minimum = cmach_packsize[packoffs]; + if (minimum < align) + align = minimum; + return align; +} + +static SInt16 CMach_GetQualifiedTypeAlign(Type *type, Boolean flag) { + Boolean r31; + SInt16 align; + + if (type->type == TYPESTRUCT && TYPE_STRUCT(type)->stype >= STRUCT_TYPE_4 && TYPE_STRUCT(type)->stype <= STRUCT_TYPE_E) + return 16; + + switch (copts.align_mode) { + case AlignMode3_1Byte: + case AlignMode8: + return 1; + case AlignMode4_2Byte: + case AlignMode5_4Byte: + case AlignMode6_8Byte: + case AlignMode7_16Byte: + r31 = 1; + break; + default: + r31 = 0; + break; + } + +restart: + switch (type->type) { + case TYPEVOID: + return 0; + case TYPEFUNC: + return 0; + case TYPEENUM: + type = TYPE_ENUM(type)->enumtype; + case TYPEINT: + if (r31) + return CMach_GetWinTypeAlign(type); + if (type->size == 1) + return 1; + if (copts.oldalignment && type->size == 8) + return 8; + if (copts.align_mode != AlignMode0_Mac68k && type->size >= 4) + return 4; + return 2; + case TYPEFLOAT: + if (r31) + return CMach_GetWinTypeAlign(type); + switch (copts.align_mode) { + case AlignMode0_Mac68k: + return 2; + case AlignMode1_Mac68k4byte: + return 4; + case AlignMode2_PPC: + if (copts.oldalignment && type->size > 4) + return 8; + return 4; + default: +#line 1346 + CError_FATAL(); + } + case TYPEMEMBERPOINTER: + case TYPEPOINTER: + if (r31) + return CMach_GetWinTypeAlign(type); + if (copts.align_mode == AlignMode0_Mac68k) + return 2; + else + return 4; + case TYPEARRAY: + if (copts.align_array_members) { + if (r31) + return CMach_GetWinTypeAlign(type); + if (type->size == 1) + return 1; + if (copts.align_mode == AlignMode0_Mac68k || type->size <= 2) + return 2; + if (copts.align_mode == AlignMode1_Mac68k4byte || type->size < 8) + return 4; + align = CMach_GetQualifiedTypeAlign(TYPE_POINTER(type)->target, flag); + if (align > 4) + return align; + else + return 4; + } else { + type = TYPE_POINTER(type)->target; + goto restart; + } + case TYPESTRUCT: + if (flag) + align = TYPE_STRUCT(type)->align; + else + align = CMach_GetQualifiedStructAlign(TYPE_STRUCT(type), flag); + if (r31) + return CMach_GetWinMinimizeAlign(align); + else + return align; + case TYPECLASS: + if (flag) + align = TYPE_CLASS(type)->align; + else + align = CMach_GetQualifiedClassAlign(TYPE_CLASS(type), flag); + if (r31) + return CMach_GetWinMinimizeAlign(align); + else + return align; + case TYPEBITFIELD: + type = TYPE_BITFIELD(type)->bitfieldtype; + goto restart; + case TYPETEMPLATE: + return 1; + default: +#line 1392 + CError_FATAL(); + return 0; + } +} + +SInt16 CMach_GetTypeAlign(Type *type) { + return CMach_GetQualifiedTypeAlign(type, 1); +} + +static SInt16 CMach_GetMemberAlignment(Type *type, SInt32 var, Boolean flag) { + SInt32 align; + + align = CMach_GetQualifiedTypeAlign(type, flag); + if (align < 1) + align = 1; + + if (type->type == TYPESTRUCT && TYPE_STRUCT(type)->stype >= STRUCT_TYPE_4 && TYPE_STRUCT(type)->stype <= STRUCT_TYPE_E && align < 16) + align = 16; + + switch (copts.align_mode) { + case AlignMode8: + align = 1; + break; + case AlignMode0_Mac68k: + if (align > 2) + align = 2; + break; + case AlignMode1_Mac68k4byte: + if (align > 4) + align = 4; + break; + case AlignMode2_PPC: + if (!copts.oldalignment) + align = CMach_GetPPCTypeAlign(type, !cmach_structoffset || (cmach_structalign >= 8), flag); + if (var > align) + align = var; + break; + } + + if (align > cmach_structalign) + cmach_structalign = align; + return align; +} + +SInt16 CMach_MemberAlignValue(Type *type, SInt32 var) { + SInt16 align = CMach_GetMemberAlignment(type, 0, 1); + if (align <= 1) + return 0; + + return (align - 1) & (align - (var & (align - 1))); +} + +static SInt16 MemberAlignValue(Type *type, SInt32 var1, SInt32 var2) { + SInt16 align = CMach_GetMemberAlignment(type, var2, 1); + return (align - 1) & (align - (var1 & (align - 1))); +} + +void CMach_StructLayoutInitOffset(SInt32 offset) { + cmach_structoffset = offset; + cmach_structalign = 4; + cmach_curbfsize = 0; +} + +SInt32 CMach_StructLayoutGetCurSize() { + return cmach_structoffset; +} + +SInt32 CMach_StructLayoutGetOffset(Type *type, UInt32 qual) { + SInt32 align; + SInt32 offset; + + qual = CParser_GetTypeQualifiers(type, qual); + + cmach_curbfsize = 0; + align = MemberAlignValue(type, cmach_structoffset, CMach_GetQUALalign(qual)); + offset = cmach_structoffset + align; + cmach_structoffset = offset + type->size; + return offset; +} + +SInt32 CMach_StructLayoutBitfield(TypeBitfield *tbitfield, UInt32 qual) { + SInt16 align; + SInt16 padding_at_start; + SInt16 basesize; + SInt16 basesize_bits; + SInt16 required_alignment; + SInt16 r4; + + padding_at_start = 0; + required_alignment = 0; + align = CMach_GetQUALalign(qual); + if (align <= tbitfield->bitfieldtype->size) + align = 0; + + switch (tbitfield->bitfieldtype->size) { + case 1: + basesize = 1; + basesize_bits = 8; + required_alignment = 0; + break; + case 2: + basesize = 2; + basesize_bits = 16; + required_alignment = 2; + break; + case 4: + if (copts.align_mode != AlignMode0_Mac68k && copts.align_mode != AlignMode4_2Byte) + required_alignment = 4; + else + required_alignment = 2; + basesize = 4; + basesize_bits = 32; + break; + default: +#line 1620 + CError_FATAL(); + } + + switch (copts.align_mode) { + case AlignMode3_1Byte: + case AlignMode8: + required_alignment = 0; + break; + } + + r4 = required_alignment; + if (align > required_alignment) + r4 = align; + if (r4 && (cmach_structoffset & (r4 - 1))) + padding_at_start = r4 - (cmach_structoffset & (r4 - 1)); + + if (!cmach_curbfsize) { + cmach_structoffset += padding_at_start; + if (!tbitfield->unkB) + return cmach_structoffset; + cmach_curbfsize = tbitfield->unkB; + cmach_curbfbasesize = basesize; + cmach_curbfoffset = cmach_structoffset; + cmach_structoffset += basesize; + tbitfield->unkA = 0; + return cmach_curbfoffset; + } else { + if (!tbitfield->unkB || (cmach_curbfsize + tbitfield->unkB) > basesize_bits || cmach_curbfbasesize != basesize) { + cmach_structoffset += padding_at_start; + cmach_curbfsize = 0; + cmach_curbfbasesize = basesize; + if (!tbitfield->unkB) + return cmach_structoffset; + cmach_curbfoffset = cmach_structoffset; + cmach_structoffset += basesize; + } + tbitfield->unkA = cmach_curbfsize; + cmach_curbfsize += tbitfield->unkB; + return cmach_curbfoffset; + } +} + +static Boolean CMach_IsTrivialClass(TypeClass *tclass) { + return !CClass_Constructor(tclass); +} + +UInt8 CMach_GetFunctionResultClass(TypeFunc *tfunc) { + switch (tfunc->functype->type) { + case TYPESTRUCT: + if (tfunc->functype->type == TYPESTRUCT && TYPE_STRUCT(tfunc->functype)->stype >= STRUCT_TYPE_4 && TYPE_STRUCT(tfunc->functype)->stype <= STRUCT_TYPE_E) + return 0; + case TYPECLASS: + case TYPEMEMBERPOINTER: + return CMach_PassResultInHiddenArg(tfunc->functype) ? 1 : 0; + default: + return 0; + } +} + +Boolean CMach_PassResultInHiddenArg(Type *type) { + switch (type->type) { + case TYPESTRUCT: + if (TYPE_STRUCT(type)->stype >= STRUCT_TYPE_4 && TYPE_STRUCT(type)->stype <= STRUCT_TYPE_E) + return 0; + else + return 1; + case TYPECLASS: + return 1; + case TYPEMEMBERPOINTER: + return (type->size == 4) ? 0 : 1; + default: + return 0; + } +} + +const char *CMach_GetCPU() { + switch (copts.cpu) { + case CPU_PPC401: return "__PPC401__"; + case CPU_PPC403: return "__PPC403__"; + case CPU_PPC505: return "__PPC505__"; + case CPU_PPC509: return "__PPC509__"; + case CPU_PPC555: return "__PPC555__"; + case CPU_PPC556: return "__PPC556__"; + case CPU_PPC565: return "__PPC565__"; + case CPU_PPC601: return "__PPC601__"; + case CPU_PPC602: return "__PPC602__"; + case CPU_PPC603: return "__PPC603__"; + case CPU_PPC603e: return "__PPC603e__"; + case CPU_PPC604: return "__PPC604__"; + case CPU_PPC604e: return "__PPC604e__"; + case CPU_PPC740: return "__PPC740__"; + case CPU_PPC750: return "__PPC750__"; + case CPU_PPC801: return "__PPC801__"; + case CPU_PPC821: return "__PPC821__"; + case CPU_PPC823: return "__PPC823__"; + case CPU_PPC850: return "__PPC850__"; + case CPU_PPC860: return "__PPC860__"; + case CPU_PPC7400: return "__PPC7400__"; + case CPU_PPC7450: return "__PPC7450__"; + case CPU_PPC8240: return "__PPC8240__"; + case CPU_PPC8260: return "__PPC8260__"; + case CPU_PPCGEKKO: return "__PPCGEKKO__"; + case CPU_PPCELF: return "__PPCELF__"; + default: return NULL; + } +} + +Boolean CMach_FloatIsPowerOf2(Float flt) { + return (flt.value == 2.0) || + (flt.value == 4.0) || + (flt.value == 8.0) || + (flt.value == 16.0) || + (flt.value == 32.0) || + (flt.value == 64.0) || + (flt.value == 128.0) || + (flt.value == 256.0) || + (flt.value == 512.0) || + (flt.value == 1024.0); +} + +Float CMach_FloatReciprocal(Float flt) { + flt.value = 1.0 / flt.value; + return flt; +} + +SInt32 CMach_RoundedSizeOf(Object *object) { + SInt32 size = object->type->size; + SInt32 align = CMach_GetTypeAlign(object->type) - 1; + return (size + align) & ~align; +} + +void CMach_ReInitRuntimeObjects() { + HashNameNode *e0 = GetHashNameNodeExport("[0]"); + HashNameNode *e1 = GetHashNameNodeExport("[1]"); + HashNameNode *e2 = GetHashNameNodeExport("[2]"); + HashNameNode *e3 = GetHashNameNodeExport("[3]"); + HashNameNode *e4 = GetHashNameNodeExport("[4]"); + HashNameNode *e5 = GetHashNameNodeExport("[5]"); + HashNameNode *e6 = GetHashNameNodeExport("[6]"); + HashNameNode *e7 = GetHashNameNodeExport("[7]"); + HashNameNode *e8 = GetHashNameNodeExport("[8]"); + HashNameNode *e9 = GetHashNameNodeExport("[9]"); + HashNameNode *e10 = GetHashNameNodeExport("[10]"); + HashNameNode *e11 = GetHashNameNodeExport("[11]"); + HashNameNode *e12 = GetHashNameNodeExport("[12]"); + HashNameNode *e13 = GetHashNameNodeExport("[13]"); + HashNameNode *e14 = GetHashNameNodeExport("[14]"); + HashNameNode *e15 = GetHashNameNodeExport("[15]"); + HashNameNode *vuc = GetHashNameNodeExport("vector unsigned char"); + HashNameNode *vus = GetHashNameNodeExport("vector unsigned short"); + HashNameNode *vui = GetHashNameNodeExport("vector unsigned int"); + HashNameNode *vsc = GetHashNameNodeExport("vector signed char"); + HashNameNode *vss = GetHashNameNodeExport("vector signed short"); + HashNameNode *vsi = GetHashNameNodeExport("vector signed int"); + HashNameNode *vbc = GetHashNameNodeExport("vector bool char"); + HashNameNode *vbs = GetHashNameNodeExport("vector bool short"); + HashNameNode *vbi = GetHashNameNodeExport("vector bool int"); + HashNameNode *vf = GetHashNameNodeExport("vector float"); + HashNameNode *vp = GetHashNameNodeExport("vector pixel"); + + stvectorunsignedchar.name = vuc; + stvectorunsignedshort.name = vus; + stvectorunsignedlong.name = vui; + stvectorsignedchar.name = vsc; + stvectorsignedshort.name = vss; + stvectorsignedlong.name = vsi; + stvectorboolchar.name = vbc; + stvectorboolshort.name = vbs; + stvectorboollong.name = vbi; + stvectorfloat.name = vf; + stvectorpixel.name = vp; + + stVUC_unsignedchar0.name = e0; + stVUC_unsignedchar1.name = e1; + stVUC_unsignedchar2.name = e2; + stVUC_unsignedchar3.name = e3; + stVUC_unsignedchar4.name = e4; + stVUC_unsignedchar5.name = e5; + stVUC_unsignedchar6.name = e6; + stVUC_unsignedchar7.name = e7; + stVUC_unsignedchar8.name = e8; + stVUC_unsignedchar9.name = e9; + stVUC_unsignedchar10.name = e10; + stVUC_unsignedchar11.name = e11; + stVUC_unsignedchar12.name = e12; + stVUC_unsignedchar13.name = e13; + stVUC_unsignedchar14.name = e14; + stVUC_unsignedchar15.name = e15; + stVSC_signedchar0.name = e0; + stVSC_signedchar1.name = e1; + stVSC_signedchar2.name = e2; + stVSC_signedchar3.name = e3; + stVSC_signedchar4.name = e4; + stVSC_signedchar5.name = e5; + stVSC_signedchar6.name = e6; + stVSC_signedchar7.name = e7; + stVSC_signedchar8.name = e8; + stVSC_signedchar9.name = e9; + stVSC_signedchar10.name = e10; + stVSC_signedchar11.name = e11; + stVSC_signedchar12.name = e12; + stVSC_signedchar13.name = e13; + stVSC_signedchar14.name = e14; + stVSC_signedchar15.name = e15; + + stVUS_unsignedshort0.name = e0; + stVUS_unsignedshort1.name = e1; + stVUS_unsignedshort2.name = e2; + stVUS_unsignedshort3.name = e3; + stVUS_unsignedshort4.name = e4; + stVUS_unsignedshort5.name = e5; + stVUS_unsignedshort6.name = e6; + stVUS_unsignedshort7.name = e7; + stVSS_signedshort0.name = e0; + stVSS_signedshort1.name = e1; + stVSS_signedshort2.name = e2; + stVSS_signedshort3.name = e3; + stVSS_signedshort4.name = e4; + stVSS_signedshort5.name = e5; + stVSS_signedshort6.name = e6; + stVSS_signedshort7.name = e7; + + stVUL_unsignedlong0.name = e0; + stVUL_unsignedlong1.name = e1; + stVUL_unsignedlong2.name = e2; + stVUL_unsignedlong3.name = e3; + stVSL_signedlong0.name = e0; + stVSL_signedlong1.name = e1; + stVSL_signedlong2.name = e2; + stVSL_signedlong3.name = e3; + + stVF_float0.name = e0; + stVF_float1.name = e1; + stVF_float2.name = e2; + stVF_float3.name = e3; +} diff --git a/compiler_and_linker/unsorted/CPrec.c b/compiler_and_linker/unsorted/CPrec.c new file mode 100644 index 0000000..a879df6 --- /dev/null +++ b/compiler_and_linker/unsorted/CPrec.c @@ -0,0 +1,2142 @@ +#include "compiler.h" +#include "compiler/CompilerTools.h" +#include "compiler/CError.h" +#include "compiler/enode.h" +#include "compiler/objc.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" +#include "compiler/som.h" +#include "compiler/templates.h" +#include "compiler/types.h" +#include "cos.h" + +// HACKS +extern Type stvoid; +extern Type stbool; +extern Type stchar; +extern Type stsignedchar; +extern Type stunsignedchar; +extern Type stwchar; +extern Type stsignedshort; +extern Type stunsignedshort; +extern Type stsignedint; +extern Type stunsignedint; +extern Type stsignedlong; +extern Type stunsignedlong; +extern Type stsignedlonglong; +extern Type stunsignedlonglong; +extern Type stfloat; +extern Type stshortdouble; +extern Type stdouble; +extern Type stlongdouble; +extern Type elipsis; +extern Type oldstyle; +extern Type stillegal; +extern Type sttemplexpr; +extern Type stvoid; +extern Type void_ptr; +extern Type rt_func; +extern Type catchinfostruct; +extern void * newh_func; +extern void * delh_func; +extern void * copy_func; +extern void * clear_func; +extern void * Rgtid_func; +extern void * Rdync_func; +extern void * rt_ptmf_cast; +extern void * rt_ptmf_cmpr; +extern void * rt_ptmf_test; +extern void * rt_ptmf_call; +extern void * rt_ptmf_scall; +extern void * rt_ptmf_null; +extern void * rt_som_glue1; +extern void * rt_som_glue2; +extern void * rt_som_glue3; +extern void * rt_som_check; +extern void * rt_som_new; +extern void * rt_som_newcheck; +extern void * rt_ptmf_call4; +extern void * rt_ptmf_scall4; +extern void * carr_func; +extern void * cnar_func; +extern void * darr_func; +extern void * dnar_func; +extern void * dnar3_func; +extern void * Xgreg_func; +extern void * Xthrw_func; +extern void * Xicth_func; +extern void * Xecth_func; +extern void * Xunex_func; +extern Type stvectorunsignedchar; +extern Type stvectorsignedchar; +extern Type stvectorboolchar; +extern Type stvectorunsignedshort; +extern Type stvectorsignedshort; +extern Type stvectorboolshort; +extern Type stvectorunsignedlong; +extern Type stvectorsignedlong; +extern Type stvectorboollong; +extern Type stvectorfloat; +extern Type stvectorpixel; +// HACKS + +// PUBLIC FUNCTIONS +extern void SetupPrecompiler(); +extern void CleanupPrecompiler(); +extern void PreComp_StaticData(Object *obj, const void *data, void *unk1, void *unk2); +extern void PrecompilerWrite(); +extern void PrecompilerRead(short refnum, void *buffer); +// END PUBLIC FUNCTIONS + +typedef struct Patch { + struct Patch *next; + SInt32 offset; +} Patch; + +typedef struct AddrPatch { + struct AddrPatch *next; + void *addr; + void *value; +} AddrPatch; + +typedef struct BuiltIn { + void *target; + SInt32 idx; + Patch *patches; +} BuiltIn; + +static Boolean cprec_exportargnames; +static Boolean cprec_dowrite; +static OSErr cprec_ioerror; +static void *cprec_rawbuffer; +static void *cprec_buffer; +static SInt32 cprec_zero_offset; +static SInt32 cprec_offset; +static int cprec_builtins; +static void **cprec_builtin_array; + +typedef struct TokenPatch { + struct TokenPatch *next; + TStreamElement *tokens; + SInt32 count; +} TokenPatch; +static TokenPatch *cprec_tokenpatches; + +static void *cprec_staticdata; +static void *cprec_pointerhash; +static BuiltIn *cprec_builtin; +static Patch *cprec_patch_list; +static AddrPatch **cprec_addrhash; +static void *cprec_header; +static GList cprec_glist; +static short cprec_refnum; +char *precomp_target_str; + +// Assorted forward declarations +static NameSpace *CPrec_GetNameSpacePatch(NameSpace *nspace); +static ObjEnumConst *CPrec_GetObjEnumConstPatch(ObjEnumConst *obj); +static Object *CPrec_GetObjectPatch(Object *obj); +static ObjBase *CPrec_GetObjBasePatch(ObjBase *obj); +static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *obj); +static Type *CPrec_GetTypePatch(Type *type); +static ENode *CPrec_GetExpressionPatch(ENode *enode); +static ObjCMethod *CPrec_GetObjCMethodPatch(ObjCMethod *meth); +static ObjCProtocolList *CPrec_GetObjCProtocolListPatch(ObjCProtocolList *lst); +static TemplArg *CPrec_GetTemplateArgPatch(TemplArg *arg); +static OSErr CPrec_FlushBufferCheck(); + +void SetupPrecompiler() { + cprec_refnum = 0; + cprec_glist.data = NULL; + cprec_header = NULL; + cprec_staticdata = NULL; + cprec_ioerror = noErr; +} + +void CleanupPrecompiler() { + if (cprec_refnum) { + COS_FileClose(cprec_refnum); + cprec_refnum = 0; + } + + if (cprec_glist.data) + FreeGList(&cprec_glist); +} + +static void CPrec_OLinkListCopy() {} + +void PreComp_StaticData(Object *obj, const void *data, void *unk1, void *unk2) { + +} + +static void CPrec_InitAddressHashTable() { + cprec_addrhash = lalloc(0x4000 * sizeof(AddrPatch *)); + memclrw(cprec_addrhash, 0x4000 * sizeof(AddrPatch *)); +} + +static void CPrec_InitPointerHashTable() { + cprec_pointerhash = lalloc(0x1000); + memclrw(cprec_pointerhash, 0x1000); +} + +static int CPrec_AddressHashVal(void *addr) { + UInt32 v = (UInt32) addr; + return ( + v + + ((unsigned char *) &v)[0] + + ((unsigned char *) &v)[1] + + ((unsigned char *) &v)[2] + + ((unsigned char *) &v)[3] + ) & 0x3FFF; +} + +static AddrPatch *CPrec_FindAddrPatch(void *addr) { + AddrPatch *scan; + + for (scan = cprec_addrhash[CPrec_AddressHashVal(addr)]; scan; scan = scan->next) { + if (scan->addr == addr) + return scan; + } + + return NULL; +} + +static AddrPatch *CPrec_NewAddrPatch(void *addr, void *value) { + AddrPatch **loc; + AddrPatch *patch; + + loc = cprec_addrhash + CPrec_AddressHashVal(addr); + patch = lalloc(sizeof(AddrPatch)); + patch->addr = addr; + patch->value = value; + patch->next = *loc; + *loc = patch; + return patch; +} + +static void CPrec_SetupBuiltInArray() { + int count1, count2; + Boolean flag; + void **array; + +#define REG_BUILTIN(a) \ + if (!flag) { array[count2++] = (a); } else { count1++; } + + for (count2 = count1 = 0, flag = 1; ;) { + REG_BUILTIN(cscope_root); + REG_BUILTIN(&stvoid); + REG_BUILTIN(&stbool); + REG_BUILTIN(&stchar); + REG_BUILTIN(&stsignedchar); + REG_BUILTIN(&stunsignedchar); + REG_BUILTIN(&stwchar); + REG_BUILTIN(&stsignedshort); + REG_BUILTIN(&stunsignedshort); + REG_BUILTIN(&stsignedint); + REG_BUILTIN(&stunsignedint); + REG_BUILTIN(&stsignedlong); + REG_BUILTIN(&stunsignedlong); + REG_BUILTIN(&stsignedlonglong); + REG_BUILTIN(&stunsignedlonglong); + REG_BUILTIN(&stfloat); + REG_BUILTIN(&stshortdouble); + REG_BUILTIN(&stdouble); + REG_BUILTIN(&stlongdouble); + REG_BUILTIN(&elipsis); + REG_BUILTIN(&oldstyle); + REG_BUILTIN(&stillegal); + REG_BUILTIN(&sttemplexpr); + REG_BUILTIN(&stvoid); + REG_BUILTIN(&void_ptr); + REG_BUILTIN(&rt_func); + REG_BUILTIN(&catchinfostruct); + REG_BUILTIN(newh_func); + REG_BUILTIN(delh_func); + REG_BUILTIN(copy_func); + REG_BUILTIN(clear_func); + REG_BUILTIN(Rgtid_func); + REG_BUILTIN(Rdync_func); + REG_BUILTIN(rt_ptmf_cast); + REG_BUILTIN(rt_ptmf_cmpr); + REG_BUILTIN(rt_ptmf_test); + REG_BUILTIN(rt_ptmf_call); + REG_BUILTIN(rt_ptmf_scall); + REG_BUILTIN(rt_ptmf_null); + REG_BUILTIN(rt_som_glue1); + REG_BUILTIN(rt_som_glue2); + REG_BUILTIN(rt_som_glue3); + REG_BUILTIN(rt_som_check); + REG_BUILTIN(rt_som_new); + REG_BUILTIN(rt_som_newcheck); + REG_BUILTIN(rt_ptmf_call4); + REG_BUILTIN(rt_ptmf_scall4); + REG_BUILTIN(carr_func); + REG_BUILTIN(cnar_func); + REG_BUILTIN(darr_func); + REG_BUILTIN(dnar_func); + REG_BUILTIN(dnar3_func); + REG_BUILTIN(Xgreg_func); + REG_BUILTIN(Xthrw_func); + REG_BUILTIN(Xicth_func); + REG_BUILTIN(Xecth_func); + REG_BUILTIN(Xunex_func); + REG_BUILTIN(&stvectorunsignedchar); + REG_BUILTIN(&stvectorsignedchar); + REG_BUILTIN(&stvectorboolchar); + REG_BUILTIN(&stvectorunsignedshort); + REG_BUILTIN(&stvectorsignedshort); + REG_BUILTIN(&stvectorboolshort); + REG_BUILTIN(&stvectorunsignedlong); + REG_BUILTIN(&stvectorsignedlong); + REG_BUILTIN(&stvectorboollong); + REG_BUILTIN(&stvectorfloat); + REG_BUILTIN(&stvectorpixel); + + if (flag) { + array = lalloc(sizeof(void *) * count1); + cprec_builtin_array = array; + cprec_builtins = count1; + flag = 0; + } else { + return; + } + } +} + +static void CPrec_SetupBuiltIn() { + int x; + + CPrec_SetupBuiltInArray(); + cprec_builtin = lalloc(sizeof(BuiltIn) * cprec_builtins); + memclrw(cprec_builtin, sizeof(BuiltIn) * cprec_builtins); + + for (x = 0; x < cprec_builtins; x++) { + cprec_builtin[x].target = cprec_builtin_array[x]; + cprec_builtin[x].idx = ~x; + CPrec_NewAddrPatch(cprec_builtin[x].target, (void *) cprec_builtin[x].idx); + } +} + +static void CPrec_NewPointerPatch(void *src, void *ptr) { + if (cprec_dowrite) { + Patch *patch = lalloc(sizeof(Patch)); + patch->offset = (SInt32) src; +#line 507 + CError_ASSERT((patch->offset & 0x80000001) == 0); + + if ((SInt32) ptr < 0) { + ptr = (void *) ~((SInt32) ptr); +#line 513 + CError_ASSERT((SInt32) ptr < cprec_builtins); + + patch->next = cprec_builtin[(SInt32) ptr].patches; + cprec_builtin[(SInt32) ptr].patches = patch; + ptr = NULL; + } else { + patch->next = cprec_patch_list; + cprec_patch_list = patch; + } + + src = (void *)((char *) src - cprec_zero_offset); +#line 525 + CError_ASSERT((SInt32) src >= 0 && (SInt32) src <= cprec_glist.size); + *((void **) (*cprec_glist.data + (SInt32) src)) = ptr; + } +} + +static void CPrec_ExistingPointerPatch(void *src, void *ptr) { + if (cprec_dowrite) { + AddrPatch *addrPatch; + Patch *patch; + + addrPatch = CPrec_FindAddrPatch(ptr); +#line 543 + CError_ASSERT(addrPatch); + + patch = lalloc(sizeof(Patch)); + patch->offset = (SInt32) src; + patch->next = cprec_patch_list; + cprec_patch_list = patch; + +#line 548 + CError_ASSERT((patch->offset & 0x80000001) == 0); + + src = (void *)((char *) src - cprec_zero_offset); +#line 552 + CError_ASSERT((SInt32) src >= 0 && (SInt32) src <= cprec_glist.size); + *((void **) (*cprec_glist.data + (SInt32) src)) = addrPatch->value; + } +} + +static void CPrec_NamePatch(void *src, HashNameNode *name) { + name->id = 1; + CPrec_ExistingPointerPatch(src, name); +} + +static void *CPrec_AppendAlign() { + if (cprec_dowrite) { + while (cprec_offset & 3) { + AppendGListByte(&cprec_glist, 0); + ++cprec_offset; + } + } + + return (void *) cprec_offset; +} + +static UInt32 CPrec_AppendByte(UInt8 v) { + if (cprec_dowrite) + AppendGListByte(&cprec_glist, v); + return cprec_offset++; +} + +static UInt32 CPrec_AppendWord16(UInt16 v) { + UInt32 offset; + if (cprec_dowrite) + AppendGListWord(&cprec_glist, v); + offset = cprec_offset; + cprec_offset += 2; + return offset; +} + +static UInt32 CPrec_AppendWord32(UInt32 v) { + UInt32 offset; + if (cprec_dowrite) + AppendGListLong(&cprec_glist, v); + offset = cprec_offset; + cprec_offset += 4; + return offset; +} + +static UInt32 CPrec_AppendPointer(void *v) { + UInt32 offset; + if (cprec_dowrite) + AppendGListLong(&cprec_glist, (SInt32) v); + offset = cprec_offset; + cprec_offset += 4; + return offset; +} + +static UInt32 CPrec_AppendPointerPatch(void *v) { + AddrPatch *addrPatch; + + if (v) { + addrPatch = CPrec_FindAddrPatch(v); +#line 644 + CError_ASSERT(addrPatch); + + if (cprec_dowrite) { + Patch *patch = lalloc(sizeof(Patch)); + patch->offset = cprec_offset; + patch->next = cprec_patch_list; + cprec_patch_list = patch; +#line 651 + CError_ASSERT((patch->offset & 0x80000001) == 0); + } + + return CPrec_AppendPointer(addrPatch->value); + } else { + return CPrec_AppendPointer(NULL); + } +} + +static void CPrec_AppendNamePatch(HashNameNode *name) { + if (name) { + CPrec_AppendPointerPatch(name); + name->id = 1; + } +} + +static void CPrec_AppendString(const char *str) { + int len = strlen(str) + 1; + if (cprec_dowrite) + AppendGListData(&cprec_glist, str, len); + cprec_offset += len; +} + +static void CPrec_AppendData(const void *data, int len) { + if (cprec_dowrite) + AppendGListData(&cprec_glist, data, len); + cprec_offset += len; +} + +static void CPrec_RawMemPatch(void *source, const void *data, int len) { + void *ptr = CPrec_AppendAlign(); + CPrec_AppendData(data, len); + CPrec_NewPointerPatch(source, ptr); +} + +static void CPrec_DumpNameTable() {} +static void CPrec_DumpMacroTable() {} +static void CPrec_GetClassAccessPatch() {} + +static int CPrec_PointerHash(TypePointer *type) { + Type *target; + int work; + FuncArg *arg; + + work = type->qual; + target = type->target; + +restart: + switch (target->type) { + case TYPECLASS: + if (TYPE_CLASS(target)->classname) + work += TYPE_CLASS(target)->classname->hashval; + break; + case TYPEENUM: + if (TYPE_ENUM(target)->enumname) + work += TYPE_ENUM(target)->enumname->hashval; + target = TYPE_ENUM(target)->enumtype; + work += 3; + case TYPEINT: + case TYPEFLOAT: + work += TYPE_INTEGRAL(target)->integral; + break; + case TYPEPOINTER: + work += TYPE_POINTER(target)->qual; + target = TYPE_POINTER(target)->target; + goto restart; + case TYPEARRAY: + work += target->size; + target = TYPE_POINTER(target)->target; + goto restart; + case TYPEFUNC: + work += TYPE_FUNC(target)->functype->type; + work += TYPE_FUNC(target)->functype->size; + for (arg = TYPE_FUNC(target)->args; arg; arg = arg->next) { + if (arg->type) { + work += arg->type->type; + work += arg->type->size; + } + } + break; + } + + work += target->type + target->size; + return (work + (work >> 24) + (work >> 16) + (work >> 8)) & 0x3FF; +} + +static TypePointer *CPrec_GetTypePointerPatch(TypePointer *type) { + // requires copts +} + +static TypeEnum *CPrec_GetTypeEnumPatch(TypeEnum *type) { + TypeEnum *p = CPrec_AppendAlign(); + + CPrec_NewAddrPatch(type, p); + CPrec_AppendData(type, sizeof(TypeEnum)); + + if (type->nspace) + CPrec_NewPointerPatch(&p->nspace, CPrec_GetNameSpacePatch(type->nspace)); + if (type->enumlist) + CPrec_NewPointerPatch(&p->enumlist, CPrec_GetObjEnumConstPatch(type->enumlist)); + + CPrec_NewPointerPatch(&p->enumtype, CPrec_GetTypePatch(type->enumtype)); + if (type->enumname) + CPrec_NamePatch(&p->enumname, type->enumname); + + return p; +} + +static TypeBitfield *CPrec_GetTypeBitfieldPatch(TypeBitfield *type) { + TypeBitfield *p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(type, p); + CPrec_AppendData(type, sizeof(TypeBitfield)); + + CPrec_NewPointerPatch(&p->bitfieldtype, type->bitfieldtype); + + return p; +} + +static TypeStruct *CPrec_GetTypeStructPatch(TypeStruct *type) {} + +static ExceptSpecList *CPrec_GetExceptSpecPatch(ExceptSpecList *exspec) { + ExceptSpecList *first, *current, *next; + + first = current = CPrec_AppendAlign(); + while (exspec) { + CPrec_AppendData(exspec, sizeof(ExceptSpecList)); + if (exspec->type) + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(exspec->type)); + + if (!exspec->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + exspec = exspec->next; + } + + return first; +} + +static FuncArg *CPrec_GetArgListPatch(FuncArg *lst, Boolean includeNames) { + // too many register swaps + AddrPatch *addrPatch; + FuncArg *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(lst))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); +restart: + if (!includeNames) + lst->name = NULL; + CPrec_AppendData(lst, sizeof(FuncArg)); + if (includeNames && lst->name) + CPrec_NamePatch(¤t->name, lst->name); + + if (lst->dexpr) + CPrec_NewPointerPatch(¤t->dexpr, CPrec_GetExpressionPatch(lst->dexpr)); + if (lst->type) + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(lst->type)); + else +#line 1167 + CError_FATAL(); + + if (lst->next) { + if ((addrPatch = CPrec_FindAddrPatch(lst->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + lst = lst->next; + CPrec_NewAddrPatch(lst, next); + goto restart; + } + } + + return first; +} + +static TypeFunc *CPrec_GetTypeFuncPatch(TypeFunc *type) { + TypeFunc *p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(type, p); + + CPrec_AppendData(type, (type->flags & FUNC_FLAGS_METHOD) ? sizeof(TypeMethod) : sizeof(TypeFunc)); + + CPrec_NewPointerPatch(&p->functype, CPrec_GetTypePatch(type->functype)); + if (type->args) + CPrec_NewPointerPatch(&p->args, CPrec_GetArgListPatch(type->args, (type->flags & FUNC_FLAGS_900000) != 0)); + if (type->exspecs) + CPrec_NewPointerPatch(&p->exspecs, CPrec_GetExceptSpecPatch(type->exspecs)); + if (type->flags & FUNC_FLAGS_METHOD) + CPrec_NewPointerPatch(&TYPE_METHOD(p)->theclass, CPrec_GetTypePatch((Type *) TYPE_METHOD(type)->theclass)); + + return p; +} + +static TypeMemberPointer *CPrec_GetTypeMemberPointerPatch(TypeMemberPointer *type) { + TypeMemberPointer *p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(type, p); + + CPrec_AppendData(type, sizeof(TypeMemberPointer)); + + CPrec_NewPointerPatch(&p->ty1, CPrec_GetTypePatch(type->ty1)); + CPrec_NewPointerPatch(&p->ty2, CPrec_GetTypePatch(type->ty2)); + + return p; +} + +static TypeTemplDep *CPrec_GetTypeTemplDepPatch(TypeTemplDep *type) { + TypeTemplDep *p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(type, p); + + CPrec_AppendData(type, sizeof(TypeTemplDep)); + + switch (type->dtype) { + case TEMPLDEP_ARGUMENT: + break; + case TEMPLDEP_QUALNAME: + CPrec_NewPointerPatch(&p->u.qual.type, CPrec_GetTypeTemplDepPatch(type->u.qual.type)); + CPrec_NamePatch(&p->u.qual.name, type->u.qual.name); + break; + case TEMPLDEP_TEMPLATE: + CPrec_NewPointerPatch(&p->u.templ.templ, CPrec_GetTypePatch((Type *) type->u.templ.templ)); + CPrec_NewPointerPatch(&p->u.templ.args, CPrec_GetTemplateArgPatch(type->u.templ.args)); + break; + case TEMPLDEP_ARRAY: + CPrec_NewPointerPatch(&p->u.array.type, CPrec_GetTypePatch(type->u.array.type)); + CPrec_NewPointerPatch(&p->u.array.index, CPrec_GetExpressionPatch(type->u.array.index)); + break; + case TEMPLDEP_QUALTEMPL: + CPrec_NewPointerPatch(&p->u.qualtempl.type, CPrec_GetTypeTemplDepPatch(type->u.qualtempl.type)); + CPrec_NewPointerPatch(&p->u.qualtempl.args, CPrec_GetTemplateArgPatch(type->u.qualtempl.args)); + break; + case TEMPLDEP_BITFIELD: + CPrec_NewPointerPatch(&p->u.bitfield.type, CPrec_GetTypePatch(type->u.bitfield.type)); + CPrec_NewPointerPatch(&p->u.bitfield.size, CPrec_GetExpressionPatch(type->u.bitfield.size)); + break; + default: +#line 1295 + CError_FATAL(); + } + + return p; +} + +static ClassList *CPrec_GetClassListPatch(ClassList *cl) { + AddrPatch *addrPatch; + ClassList *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(cl))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(cl, first); + + do { + CPrec_AppendData(cl, sizeof(ClassList)); + CPrec_NewPointerPatch(¤t->base, CPrec_GetTypePatch((Type *) cl->base)); + + if (!cl->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(cl->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + cl = cl->next; + } + } while (1); + + return first; +} + +static VClassList *CPrec_GetVClassListPatch(VClassList *vcl) { + VClassList *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(vcl, sizeof(VClassList)); + CPrec_NewPointerPatch(¤t->base, CPrec_GetTypePatch((Type *) vcl->base)); + + if (!vcl->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + vcl = vcl->next; + } while (1); + + return first; +} + +static ClassFriend *CPrec_GetClassFriendPatch(ClassFriend *cf) { + ClassFriend *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(cf, sizeof(ClassFriend)); + if (cf->isclass) + CPrec_NewPointerPatch(¤t->u.theclass, CPrec_GetTypePatch((Type *) cf->u.theclass)); + else + CPrec_NewPointerPatch(¤t->u.theclass, CPrec_GetObjectPatch(cf->u.obj)); + + if (!cf->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + cf = cf->next; + } while (1); + + return first; +} + +static BClassList *CPrec_GetBClassListPatch(BClassList *bcl) { + BClassList *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(bcl, sizeof(BClassList)); + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch((Type *) bcl->type)); + + if (!bcl->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + bcl = bcl->next; + } while (1); + + return first; +} + +static VTable *CPrec_GetVTablePatch(VTable *vtbl) { + VTable *p = CPrec_AppendAlign(); + CPrec_AppendData(vtbl, sizeof(VTable)); + + if (vtbl->object) + CPrec_NewPointerPatch(&p->object, CPrec_GetObjectPatch(vtbl->object)); + if (vtbl->owner) + CPrec_NewPointerPatch(&p->owner, CPrec_GetTypePatch((Type *) vtbl->owner)); + + return p; +} + +static SOMReleaseOrder *CPrec_GetSOMReleaseOrderPatch(SOMReleaseOrder *sro) { + SOMReleaseOrder *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(sro, sizeof(SOMReleaseOrder)); + CPrec_NamePatch(¤t->name, sro->name); + if (!sro->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + sro = sro->next; + } while (1); + + return first; +} + +static SOMInfo *CPrec_GetSOMInfoPatch(SOMInfo *som) { + SOMInfo *p = CPrec_AppendAlign(); + CPrec_AppendData(som, sizeof(SOMInfo)); + + if (som->metaclass) + CPrec_NewPointerPatch(&p->metaclass, CPrec_GetTypePatch((Type *) som->metaclass)); + if (som->classdataobject) + CPrec_NewPointerPatch(&p->classdataobject, CPrec_GetObjectPatch(som->classdataobject)); + if (som->order) + CPrec_NewPointerPatch(&p->order, CPrec_GetSOMReleaseOrderPatch(som->order)); + + return p; +} + +static ObjCMethodArg *CPrec_GetObjCMethodArgPatch(ObjCMethodArg *arg) { + ObjCMethodArg *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(arg, sizeof(ObjCMethodArg)); + if (arg->selector) + CPrec_NamePatch(¤t->selector, arg->selector); + if (arg->name) + CPrec_NamePatch(¤t->name, arg->name); + if (arg->type) + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(arg->type)); + + if (!arg->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + arg = arg->next; + } while (1); + + return first; +} + +static ObjCMethodList *CPrec_GetObjCMethodListPatch(ObjCMethodList *lst) { + AddrPatch *addrPatch; + ObjCMethodList *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(lst))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(lst, first); + + do { + CPrec_AppendData(lst, sizeof(ObjCMethodList)); + if (lst->method) + CPrec_NewPointerPatch(¤t->method, CPrec_GetObjCMethodPatch(lst->method)); + + if (!lst->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(lst->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + lst = lst->next; + CPrec_NewAddrPatch(lst, next); + } + } while (1); + + return first; +} + +static ObjCSelector *CPrec_GetObjCSelectorPatch(ObjCSelector *sel) { + AddrPatch *addrPatch; + ObjCSelector *current, *first, *next; + + if ((addrPatch = CPrec_FindAddrPatch(sel))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(sel, first); + + do { + CPrec_AppendData(sel, sizeof(ObjCSelector)); + if (sel->selobject) + CPrec_NewPointerPatch(¤t->selobject, CPrec_GetObjectPatch(sel->selobject)); + CPrec_NamePatch(¤t->name, sel->name); + if (sel->methods) + CPrec_NewPointerPatch(¤t->methods, CPrec_GetObjCMethodListPatch(sel->methods)); + + if (!sel->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(sel->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + sel = sel->next; + CPrec_NewAddrPatch(sel, next); + } + } while (1); + + return first; +} + +static ObjCMethod *CPrec_GetObjCMethodPatch(ObjCMethod *meth) { + // does not match - affected by weirdness where the arg goes into r31 instead of r28 + AddrPatch *addrPatch; + ObjCMethod *current, *first, *next; + + if ((addrPatch = CPrec_FindAddrPatch(meth))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(meth, first); + + do { + CPrec_AppendData(meth, sizeof(ObjCMethod)); + if (meth->object) + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(meth->object)); + if (meth->functype) + CPrec_NewPointerPatch(¤t->functype, CPrec_GetTypePatch((Type *) meth->functype)); + if (meth->selector) + CPrec_NewPointerPatch(¤t->selector, CPrec_GetObjCSelectorPatch(meth->selector)); + if (meth->return_type) + CPrec_NewPointerPatch(¤t->return_type, CPrec_GetTypePatch(meth->return_type)); + if (meth->selector_args) + CPrec_NewPointerPatch(¤t->selector_args, CPrec_GetObjCMethodArgPatch(meth->selector_args)); + + if (!meth->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(meth->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + meth = meth->next; + CPrec_NewAddrPatch(meth, next); + } + } while (1); + + return first; +} + +static ObjCProtocol *CPrec_GetObjCProtocolPatch(ObjCProtocol *prot) { + AddrPatch *addrPatch; + ObjCProtocol *current, *first, *next; + + if ((addrPatch = CPrec_FindAddrPatch(prot))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(prot, first); + + do { + CPrec_AppendData(prot, sizeof(ObjCProtocol)); + CPrec_NamePatch(¤t->name, prot->name); + if (prot->protocols) + CPrec_NewPointerPatch(¤t->protocols, CPrec_GetObjCProtocolListPatch(prot->protocols)); + if (prot->methods) + CPrec_NewPointerPatch(¤t->methods, CPrec_GetObjCMethodPatch(prot->methods)); + if (prot->object) + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(prot->object)); + + if (!prot->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(prot->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + prot = prot->next; + CPrec_NewAddrPatch(prot, next); + } + } while (1); + + return first; +} + +static ObjCProtocolList *CPrec_GetObjCProtocolListPatch(ObjCProtocolList *lst) { + AddrPatch *addrPatch; + ObjCProtocolList *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(lst))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(lst, first); + + do { + CPrec_AppendData(lst, sizeof(ObjCProtocolList)); + CPrec_NewPointerPatch(¤t->protocol, CPrec_GetObjCProtocolPatch(lst->protocol)); + + if (!lst->next) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + lst = lst->next; + } while (1); + + return first; +} + +static ObjCCategory *CPrec_GetObjCCategoryPatch(ObjCCategory *cat) { + AddrPatch *addrPatch; + ObjCCategory *current, *first, *next; + + if ((addrPatch = CPrec_FindAddrPatch(cat))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(cat, first); + + do { + CPrec_AppendData(cat, sizeof(ObjCCategory)); + CPrec_NamePatch(¤t->name, cat->name); + if (cat->protocols) + CPrec_NewPointerPatch(¤t->protocols, CPrec_GetObjCProtocolListPatch(cat->protocols)); + if (cat->methods) + CPrec_NewPointerPatch(¤t->methods, CPrec_GetObjCMethodPatch(cat->methods)); + + if (!cat->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(cat->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + cat = cat->next; + CPrec_NewAddrPatch(cat, next); + } + } while (1); + + return first; +} + +static ObjCInfo *CPrec_GetObjCInfoPatch(ObjCInfo *info) { + ObjCInfo *p = CPrec_AppendAlign(); + CPrec_AppendData(info, sizeof(ObjCInfo)); + + if (info->classobject) + CPrec_NewPointerPatch(&p->classobject, CPrec_GetObjectPatch(info->classobject)); + if (info->metaobject) + CPrec_NewPointerPatch(&p->metaobject, CPrec_GetObjectPatch(info->metaobject)); + if (info->classrefobj) + CPrec_NewPointerPatch(&p->classrefobj, CPrec_GetObjectPatch(info->classrefobj)); + if (info->methods) + CPrec_NewPointerPatch(&p->methods, CPrec_GetObjCMethodPatch(info->methods)); + if (info->protocols) + CPrec_NewPointerPatch(&p->protocols, CPrec_GetObjCProtocolListPatch(info->protocols)); + if (info->categories) + CPrec_NewPointerPatch(&p->categories, CPrec_GetObjCCategoryPatch(info->categories)); + + return p; +} + +static TemplArg *CPrec_GetTemplateArgPatch(TemplArg *arg) { + TemplArg *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(arg, sizeof(TemplArg)); + switch (arg->pid.type) { + case TPT_TYPE: + if (arg->data.typeparam.type) + CPrec_NewPointerPatch(¤t->data.typeparam.type, CPrec_GetTypePatch(arg->data.typeparam.type)); + break; + case TPT_NONTYPE: + if (arg->data.paramdecl.expr) + CPrec_NewPointerPatch(¤t->data.paramdecl.expr, CPrec_GetExpressionPatch(arg->data.paramdecl.expr)); + break; + case TPT_TEMPLATE: + if (arg->data.ttargtype) + CPrec_NewPointerPatch(¤t->data.ttargtype, CPrec_GetTypePatch(arg->data.ttargtype)); + break; + default: +#line 1879 + CError_FATAL(); + } + + if (!arg->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + arg = arg->next; + } while (1); + + return first; +} + +static TemplParam *CPrec_GetTemplateParamPatch(TemplParam *param) { + // register swap issues + TemplParam *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(param, sizeof(TemplParam)); + if (param->name) + CPrec_NamePatch(¤t->name, param->name); + + switch (param->pid.type) { + case TPT_TYPE: + if (param->data.typeparam.type) + CPrec_NewPointerPatch(¤t->data.typeparam.type, CPrec_GetTypePatch(param->data.typeparam.type)); + break; + case TPT_NONTYPE: + CPrec_NewPointerPatch(¤t->data.paramdecl.type, CPrec_GetTypePatch(param->data.paramdecl.type)); + if (param->data.paramdecl.defaultarg) + CPrec_NewPointerPatch(¤t->data.paramdecl.defaultarg, CPrec_GetExpressionPatch(param->data.paramdecl.defaultarg)); + break; + case TPT_TEMPLATE: + if (param->data.templparam.plist) + CPrec_NewPointerPatch(¤t->data.templparam.plist, CPrec_GetTemplateParamPatch(param->data.templparam.plist)); +#line 1953 + CError_ASSERT(!param->data.templparam.defaultarg); + break; + default: +#line 1958 + CError_FATAL(); + } + + if (!param->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + param = param->next; + } while (1); + + return first; +} + +static TStreamElement *CPrec_GetTStreamPatch(TStreamElement *tokens, SInt32 count) { + TStreamElement elem; + TStreamElement *first, *current, *scan; + SInt32 x; + + scan = tokens; + x = 0; + while (x < count) { + elem = *scan; + memclrw(scan, sizeof(TStreamElement)); + + scan->tokentype = elem.tokentype; + switch (elem.tokentype) { + case TK_IDENTIFIER: + scan->data.tkidentifier = elem.data.tkidentifier; + break; + case TK_INTCONST: + scan->subtype = elem.subtype; + scan->data.tkintconst = elem.data.tkintconst; + break; + case TK_FLOATCONST: + scan->subtype = elem.subtype; + scan->data.tkfloatconst = elem.data.tkfloatconst; + break; + case TK_STRING: + case TK_STRING_WIDE: + scan->subtype = elem.subtype; + scan->data.tkstring = elem.data.tkstring; + break; + } + x++; + scan++; + } + + first = current = CPrec_AppendAlign(); + CPrec_AppendData(tokens, count * sizeof(TStreamElement)); + + if (cprec_dowrite) { + TokenPatch *tp = lalloc(sizeof(TokenPatch)); + tp->tokens = current; + tp->count = count; + tp->next = cprec_tokenpatches; + cprec_tokenpatches = tp; + } + + x = 0; + while (x < count) { + switch (tokens->tokentype) { + case TK_IDENTIFIER: + CPrec_NamePatch(¤t->data.tkidentifier, tokens->data.tkidentifier); + break; + case TK_INTCONST: + case TK_FLOATCONST: + break; + case TK_STRING: + case TK_STRING_WIDE: + CPrec_RawMemPatch(¤t->data.tkstring.data, tokens->data.tkstring.data, tokens->data.tkstring.size); + break; + case TK_NEG7: + break; + default: + if (tokens->tokentype < 0) +#line 2063 + CError_FATAL(); + } + x++; + tokens++; + current++; + } + + return first; +} + +static TemplFuncInstance *CPrec_GetTemplFuncInstancePatch(TemplFuncInstance *inst) { + AddrPatch *addrPatch; + TemplFuncInstance *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(inst))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(inst, first); + + do { + CPrec_AppendData(inst, sizeof(TemplFuncInstance)); + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(inst->object)); + CPrec_NewPointerPatch(¤t->args, CPrec_GetTemplateArgPatch(inst->args)); + + if (!inst->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(inst->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + inst = inst->next; + CPrec_NewAddrPatch(inst, next); + } + } while (1); + + return first; +} + +static TemplateMember *CPrec_GetTemplateMemberPatch(TemplateMember *memb) { + TemplateMember *current, *first, *next; + first = current = CPrec_AppendAlign(); + + do { + memclrw(&memb->fileoffset, sizeof(FileOffsetInfo)); + memb->srcfile = NULL; + memb->startoffset = 0; + memb->endoffset = 0; + + CPrec_AppendData(memb, sizeof(TemplateMember)); + if (memb->params) + CPrec_NewPointerPatch(¤t->params, CPrec_GetTemplateParamPatch(memb->params)); + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(memb->object)); + if (memb->stream.firsttoken) + CPrec_NewPointerPatch(¤t->stream.firsttoken, CPrec_GetTStreamPatch(memb->stream.firsttoken, memb->stream.tokens)); + + if (!memb->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + memb = memb->next; + } while (1); + + return first; +} + +static TemplPartialSpec *CPrec_GetTemplPartialSpecPatch(TemplPartialSpec *pspec) { + TemplPartialSpec *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(pspec, sizeof(TemplPartialSpec)); + if (pspec->templ) + CPrec_NewPointerPatch(¤t->templ, CPrec_GetTypePatch((Type *) pspec->templ)); + if (pspec->args) + CPrec_NewPointerPatch(¤t->args, CPrec_GetTemplateArgPatch(pspec->args)); + + if (!pspec->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + pspec = pspec->next; + } while (1); + + return first; +} + +static TemplateFriend *CPrec_GetTemplateFriendPatch(TemplateFriend *frnd) { + TemplateFriend *p; + + memclrw(&frnd->fileoffset, sizeof(FileOffsetInfo)); + p = CPrec_AppendAlign(); + CPrec_AppendData(frnd, sizeof(TemplateFriend)); + + if (frnd->decl.thetype) + CPrec_NewPointerPatch(&p->decl.thetype, CPrec_GetTypePatch(frnd->decl.thetype)); + if (frnd->decl.nspace) + CPrec_NewPointerPatch(&p->decl.nspace, CPrec_GetNameSpacePatch(frnd->decl.nspace)); + if (frnd->decl.name) + CPrec_NamePatch(&p->decl.name, frnd->decl.name); + if (frnd->decl.expltargs) + CPrec_NewPointerPatch(&p->decl.expltargs, CPrec_GetTemplateArgPatch(frnd->decl.expltargs)); + if (frnd->stream.firsttoken) + CPrec_NewPointerPatch(&p->stream.firsttoken, CPrec_GetTStreamPatch(frnd->stream.firsttoken, frnd->stream.tokens)); + + return p; +} + +static TemplateAction *CPrec_GetTemplateActionPatch(TemplateAction *act) { + // register swap issue + TemplateAction *current, *first, *next; + first = current = CPrec_AppendAlign(); + + do { + memclrw(&act->source_ref, sizeof(TStreamElement)); + CPrec_AppendData(act, sizeof(TemplateAction)); + + switch (act->type) { + case TAT_NESTEDCLASS: + CPrec_NewPointerPatch(¤t->u.tclasstype, CPrec_GetTypePatch((Type *) act->u.tclasstype)); + break; + case TAT_ENUMTYPE: + CPrec_NewPointerPatch(¤t->u.enumtype, CPrec_GetTypePatch((Type *) act->u.enumtype)); + break; + case TAT_FRIEND: + CPrec_NewPointerPatch(¤t->u.tfriend, CPrec_GetTemplateFriendPatch(act->u.tfriend)); + break; + case TAT_ENUMERATOR: + CPrec_NewPointerPatch(¤t->u.enumerator.objenumconst, CPrec_GetObjEnumConstPatch(act->u.enumerator.objenumconst)); + if (act->u.enumerator.initexpr) + CPrec_NewPointerPatch(¤t->u.enumerator.initexpr, CPrec_GetExpressionPatch(act->u.enumerator.initexpr)); + break; + case TAT_BASE: + CPrec_NewPointerPatch(¤t->u.base.type, CPrec_GetTypePatch(act->u.base.type)); + if (act->u.base.insert_after) + CPrec_NewPointerPatch(¤t->u.base.insert_after, CPrec_GetClassListPatch(act->u.base.insert_after)); + break; + case TAT_OBJECTINIT: + CPrec_NewPointerPatch(¤t->u.objectinit.object, CPrec_GetObjectPatch(act->u.objectinit.object)); + CPrec_NewPointerPatch(¤t->u.objectinit.initexpr, CPrec_GetExpressionPatch(act->u.objectinit.initexpr)); + break; + case TAT_USINGDECL: + CPrec_NewPointerPatch(¤t->u.usingdecl.type, CPrec_GetTypeTemplDepPatch(act->u.usingdecl.type)); + break; + case TAT_OBJECTDEF: + CPrec_NewPointerPatch(¤t->u.refobj, CPrec_GetObjBasePatch(act->u.refobj)); + break; + default: +#line 2410 + CError_FATAL(); + } + + if (!act->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + act = act->next; + } while (1); + + return first; +} + +static TemplateFunction *CPrec_GetTemplateFunctionPatch(TemplateFunction *tf) { + // the same cursed register swaps + AddrPatch *addrPatch; + TemplateFunction *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(tf))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(tf, first); + + do { + memclrw(&tf->deftoken, sizeof(TStreamElement)); + tf->srcfile = NULL; + tf->startoffset = 0; + tf->endoffset = 0; + + CPrec_AppendData(tf, sizeof(TemplateFunction)); + if (tf->unk4) + CPrec_NewPointerPatch(¤t->unk4, CPrec_GetTemplateFunctionPatch(tf->unk4)); + CPrec_NamePatch(¤t->name, tf->name); + if (tf->params) + CPrec_NewPointerPatch(¤t->params, CPrec_GetTemplateParamPatch(tf->params)); + if (tf->stream.firsttoken) + CPrec_NewPointerPatch(¤t->stream.firsttoken, CPrec_GetTStreamPatch(tf->stream.firsttoken, tf->stream.tokens)); + CPrec_NewPointerPatch(¤t->tfunc, CPrec_GetObjectPatch(tf->tfunc)); + if (tf->instances) + CPrec_NewPointerPatch(¤t->instances, CPrec_GetTemplFuncInstancePatch(tf->instances)); + + if (!tf->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(tf->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + tf = tf->next; + CPrec_NewAddrPatch(tf, next); + } + } while (1); + + return first; +} + +static TypeClass *CPrec_GetTypeClassPatch(TypeClass *tclass) { + TypeClass *first, *current, *next; + Boolean hasNextTempl, hasNextTemplInst; + first = current = CPrec_AppendAlign(); + + do_over: + hasNextTempl = hasNextTemplInst = 0; + CPrec_NewAddrPatch(tclass, current); + + if (tclass->flags & CLASS_FLAGS_100) { + // template class + CPrec_AppendData(tclass, sizeof(TemplClass)); + if (TEMPL_CLASS(tclass)->next) + hasNextTempl = 1; + if (TEMPL_CLASS(tclass)->templ__parent) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ__parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->templ__parent)); + if (TEMPL_CLASS(tclass)->x3A_maybe_parentinst) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->x3A_maybe_parentinst, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->x3A_maybe_parentinst)); + if (TEMPL_CLASS(tclass)->templ__params) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ__params, CPrec_GetTemplateParamPatch(TEMPL_CLASS(tclass)->templ__params)); + if (TEMPL_CLASS(tclass)->members) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->members, CPrec_GetTemplateMemberPatch(TEMPL_CLASS(tclass)->members)); + if (TEMPL_CLASS(tclass)->instances) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->instances, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->instances)); + if (TEMPL_CLASS(tclass)->pspec_owner) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->pspec_owner, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->pspec_owner)); + if (TEMPL_CLASS(tclass)->pspecs) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->pspecs, CPrec_GetTemplPartialSpecPatch(TEMPL_CLASS(tclass)->pspecs)); + if (TEMPL_CLASS(tclass)->actions) + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->actions, CPrec_GetTemplateActionPatch(TEMPL_CLASS(tclass)->actions)); + } else if (tclass->flags & CLASS_FLAGS_800) { + // template class instance + CPrec_AppendData(tclass, sizeof(TemplClassInst)); + if (TEMPL_CLASS_INST(tclass)->next) + hasNextTemplInst = 1; + if (TEMPL_CLASS_INST(tclass)->x36) + CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->x36, CPrec_GetTypePatch((Type *) TEMPL_CLASS_INST(tclass)->x36)); + if (TEMPL_CLASS_INST(tclass)->templ) + CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->templ, CPrec_GetTypePatch((Type *) TEMPL_CLASS_INST(tclass)->templ)); + if (TEMPL_CLASS_INST(tclass)->inst_args) + CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->inst_args, CPrec_GetTemplateArgPatch(TEMPL_CLASS_INST(tclass)->inst_args)); + if (TEMPL_CLASS_INST(tclass)->oargs) + CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->oargs, CPrec_GetTemplateArgPatch(TEMPL_CLASS_INST(tclass)->oargs)); + } else { + // base + CPrec_AppendData(tclass, sizeof(TypeClass)); + } + + if (tclass->nspace) + CPrec_NewPointerPatch(¤t->nspace, CPrec_GetNameSpacePatch(tclass->nspace)); + if (tclass->classname) + CPrec_NamePatch(¤t->classname, tclass->classname); + if (tclass->bases) + CPrec_NewPointerPatch(¤t->bases, CPrec_GetClassListPatch(tclass->bases)); + if (tclass->vbases) + CPrec_NewPointerPatch(¤t->vbases, CPrec_GetVClassListPatch(tclass->vbases)); + if (tclass->ivars) + CPrec_NewPointerPatch(¤t->ivars, CPrec_GetObjMemberVarPatch(tclass->ivars)); + if (tclass->friends) + CPrec_NewPointerPatch(¤t->friends, CPrec_GetClassFriendPatch(tclass->friends)); + if (tclass->vtable) + CPrec_NewPointerPatch(¤t->vtable, CPrec_GetVTablePatch(tclass->vtable)); + if (tclass->sominfo) + CPrec_NewPointerPatch(¤t->sominfo, CPrec_GetSOMInfoPatch(tclass->sominfo)); + if (tclass->objcinfo) + CPrec_NewPointerPatch(¤t->objcinfo, CPrec_GetObjCInfoPatch(tclass->objcinfo)); + + if (hasNextTempl) { + AddrPatch *addrPatch = CPrec_FindAddrPatch(TEMPL_CLASS(tclass)->next); + if (!addrPatch) { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->next, next); + current = next; + tclass = (TypeClass *) TEMPL_CLASS(tclass)->next; + goto do_over; + } else { + CPrec_NewPointerPatch(&TEMPL_CLASS(current)->next, addrPatch->value); + } + } + + if (hasNextTemplInst) { + AddrPatch *addrPatch = CPrec_FindAddrPatch(TEMPL_CLASS_INST(tclass)->next); + if (!addrPatch) { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->next, next); + current = next; + tclass = (TypeClass *) TEMPL_CLASS_INST(tclass)->next; + goto do_over; + } else { + CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->next, addrPatch->value); + } + } + + return first; +} + +static Type *CPrec_GetTypePatch(Type *type) { + AddrPatch *addrPatch = CPrec_FindAddrPatch(type); + if (addrPatch) + return addrPatch->value; + + switch (type->type) { + case TYPEPOINTER: + case TYPEARRAY: + return (Type *) CPrec_GetTypePointerPatch(TYPE_POINTER(type)); + case TYPEENUM: + return (Type *) CPrec_GetTypeEnumPatch(TYPE_ENUM(type)); + case TYPEBITFIELD: + return (Type *) CPrec_GetTypeBitfieldPatch(TYPE_BITFIELD(type)); + case TYPESTRUCT: + return (Type *) CPrec_GetTypeStructPatch(TYPE_STRUCT(type)); + case TYPEFUNC: + return (Type *) CPrec_GetTypeFuncPatch(TYPE_FUNC(type)); + case TYPEMEMBERPOINTER: + return (Type *) CPrec_GetTypeMemberPointerPatch(TYPE_MEMBER_POINTER(type)); + case TYPETEMPLATE: + return (Type *) CPrec_GetTypeTemplDepPatch(TYPE_TEMPLATE(type)); + case TYPECLASS: + return (Type *) CPrec_GetTypeClassPatch(TYPE_CLASS(type)); + case TYPEVOID: + case TYPEINT: + case TYPEFLOAT: + case TYPELABEL: + case TYPEOBJCID: + case TYPETEMPLDEPEXPR: + default: +#line 2796 + CError_FATAL(); + return NULL; + } +} + +static ExceptionAction *CPrec_GetExceptionPatch(ExceptionAction *exc) { + ExceptionAction *first, *current, *next; + + first = current = CPrec_AppendAlign(); +repeat: + CPrec_AppendData(exc, sizeof(ExceptionAction)); + switch (exc->type) { + case EAT_DESTROYLOCAL: + CPrec_NewPointerPatch(¤t->data.destroy_local.dtor, CPrec_GetObjectPatch(exc->data.destroy_local.dtor)); + break; + case EAT_DESTROYLOCALCOND: + CPrec_NewPointerPatch(¤t->data.destroy_local_cond.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_cond.dtor)); + break; + case EAT_DESTROYLOCALOFFSET: + CPrec_NewPointerPatch(¤t->data.destroy_local_offset.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_offset.dtor)); + break; + case EAT_DESTROYLOCALPOINTER: + CPrec_NewPointerPatch(¤t->data.destroy_local_pointer.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_pointer.dtor)); + break; + case EAT_DESTROYLOCALARRAY: + CPrec_NewPointerPatch(¤t->data.destroy_local_array.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_array.dtor)); + break; + case EAT_DESTROYPARTIALARRAY: + break; + case EAT_DESTROYMEMBER: + case EAT_DESTROYBASE: + CPrec_NewPointerPatch(¤t->data.destroy_member.dtor, CPrec_GetObjectPatch(exc->data.destroy_member.dtor)); + break; + case EAT_DESTROYMEMBERCOND: + CPrec_NewPointerPatch(¤t->data.destroy_member_cond.dtor, CPrec_GetObjectPatch(exc->data.destroy_member_cond.dtor)); + break; + case EAT_DESTROYMEMBERARRAY: + CPrec_NewPointerPatch(¤t->data.destroy_member_array.dtor, CPrec_GetObjectPatch(exc->data.destroy_member_array.dtor)); + break; + case EAT_DELETEPOINTER: + case EAT_DELETELOCALPOINTER: + CPrec_NewPointerPatch(¤t->data.delete_pointer.deletefunc, CPrec_GetObjectPatch(exc->data.delete_pointer.deletefunc)); + break; + case EAT_DELETEPOINTERCOND: + CPrec_NewPointerPatch(¤t->data.delete_pointer_cond.deletefunc, CPrec_GetObjectPatch(exc->data.delete_pointer_cond.deletefunc)); + break; + case EAT_CATCHBLOCK: + if (exc->data.catch_block.catch_typeid) { + CPrec_NewPointerPatch(¤t->data.catch_block.catch_typeid, CPrec_GetObjectPatch(exc->data.catch_block.catch_typeid)); + CPrec_NewPointerPatch(¤t->data.catch_block.catch_type, CPrec_GetTypePatch(exc->data.catch_block.catch_type)); + } + break; + case EAT_ACTIVECATCHBLOCK: + break; + case EAT_SPECIFICATION: + if (exc->data.specification.unexp_id) { + int x; + char *ptrs; + ptrs = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->data.specification.unexp_id, ptrs); + CPrec_AppendData(exc->data.specification.unexp_id, sizeof(Object *) * exc->data.specification.unexp_ids); + for (x = 0; x < exc->data.specification.unexp_ids; x++) { + CPrec_NewPointerPatch(ptrs + x * sizeof(Object *), CPrec_GetObjectPatch(exc->data.specification.unexp_id[x])); + } + } + break; + case EAT_TERMINATE: + break; + default: +#line 2905 + CError_FATAL(); + } + + if (exc->prev) { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->prev, next); + current = next; + exc = exc->prev; + goto repeat; + } + return first; +} + +static ENodeList *CPrec_GetExpressionListPatch(ENodeList *lst) { + ENodeList *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(lst, sizeof(ENodeList)); + CPrec_NewPointerPatch(¤t->node, CPrec_GetExpressionPatch(lst->node)); + + if (!lst->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + lst = lst->next; + } while (1); + + return first; +} + +static void CPrec_GetEMemberInfoPatch() {} + +static ENode *CPrec_GetExpressionPatch(ENode *enode) { + +} + +static void CPrec_GetSwitchInfoPatch() {} +static void CPrec_GetInlineAsmPatch() {} +static void CPrec_GetStatementPatch() {} +static void CPrec_GetLocObjectPatch() {} +static void CPrec_GetInlineFuncPatch() {} + +static ObjEnumConst *CPrec_GetObjEnumConstPatch(ObjEnumConst *obj) { + AddrPatch *addrPatch; + ObjEnumConst *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(obj))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(obj, first); + + do { + CPrec_AppendData(obj, sizeof(ObjEnumConst)); + if (cprec_dowrite) { +#line 3349 + CError_ASSERT(obj->access != 255); + obj->access = 255; + } + CPrec_NamePatch(¤t->name, obj->name); + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch( obj->type)); + + if (!obj->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(obj->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + obj = obj->next; + CPrec_NewAddrPatch(obj, next); + } + } while (1); + + return first; +} + +static ObjType *CPrec_GetObjTypePatch(ObjType *obj) { + AddrPatch *addrPatch; + ObjType *p; + + if ((addrPatch = CPrec_FindAddrPatch(obj))) + return addrPatch->value; + + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(obj, p); + CPrec_AppendData(obj, sizeof(ObjType)); + CPrec_NewPointerPatch(&p->type, CPrec_GetTypePatch(obj->type)); + return p; +} + +static ObjTypeTag *CPrec_GetObjTypeTagPatch(ObjTypeTag *obj) { + AddrPatch *addrPatch; + ObjTypeTag *p; + + if ((addrPatch = CPrec_FindAddrPatch(obj))) + return addrPatch->value; + + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(obj, p); + CPrec_AppendData(obj, sizeof(ObjTypeTag)); + CPrec_NewPointerPatch(&p->type, CPrec_GetTypePatch(obj->type)); + return p; +} + +static ObjNameSpace *CPrec_GetObjNameSpacePatch(ObjNameSpace *obj) { + AddrPatch *addrPatch; + ObjNameSpace *p; + + if ((addrPatch = CPrec_FindAddrPatch(obj))) + return addrPatch->value; + + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(obj, p); + CPrec_AppendData(obj, sizeof(ObjNameSpace)); + CPrec_NewPointerPatch(&p->nspace, CPrec_GetNameSpacePatch(obj->nspace)); + return p; +} + +static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *obj) { + +} + +static DefArgCtorInfo *CPrec_GetDefArgCtorInfoPatch(DefArgCtorInfo *dac) { + DefArgCtorInfo *p = CPrec_AppendAlign(); + CPrec_AppendData(dac, sizeof(DefArgCtorInfo)); + CPrec_NewPointerPatch(&p->default_func, CPrec_GetObjectPatch(dac->default_func)); + CPrec_NewPointerPatch(&p->default_arg, CPrec_GetExpressionPatch(dac->default_arg)); + return p; +} + +static InlineXRef *CPrec_GetInlineXRefPatch(InlineXRef *ix) { + InlineXRef *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(ix, sizeof(InlineXRef) + sizeof(XRefOffset) * (ix->numxrefs - 1)); + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(ix->object)); + + if (!ix->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + ix = ix->next; + } while (1); + + return first; +} + +static Object *CPrec_GetObjectPatch(Object *o) { + +} + +static ObjBase *CPrec_GetObjBasePatch(ObjBase *obj) { + switch (obj->otype) { + default: +#line 3694 + CError_FATAL(); + case OT_ENUMCONST: + return (ObjBase *) CPrec_GetObjEnumConstPatch((ObjEnumConst *) obj); + case OT_TYPE: + return (ObjBase *) CPrec_GetObjTypePatch((ObjType *) obj); + case OT_TYPETAG: + return (ObjBase *) CPrec_GetObjTypeTagPatch((ObjTypeTag *) obj); + case OT_NAMESPACE: + return (ObjBase *) CPrec_GetObjNameSpacePatch((ObjNameSpace *) obj); + case OT_MEMBERVAR: + return (ObjBase *) CPrec_GetObjMemberVarPatch((ObjMemberVar *) obj); + case OT_OBJECT: + return (ObjBase *) CPrec_GetObjectPatch((Object *) obj); + } +} + +static ObjectList *CPrec_GetObjectListPatch(ObjectList *ol) { + AddrPatch *addrPatch; + ObjectList *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(ol))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(ol, first); +restart: + CPrec_AppendData(ol, sizeof(ObjectList)); + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(ol->object)); + if (ol->next) { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + ol = ol->next; + goto restart; + } + + return first; +} + +static NameSpaceObjectList *CPrec_GetNameSpaceObjectListPatch(NameSpaceObjectList *nsol) { + AddrPatch *addrPatch; + NameSpaceObjectList *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(nsol))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(nsol, first); + + do { + CPrec_AppendData(nsol, sizeof(NameSpaceObjectList)); + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjBasePatch(nsol->object)); + + if (!nsol->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(nsol->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + nsol = nsol->next; + CPrec_NewAddrPatch(nsol, next); + } + } while (1); + + return first; +} + +static NameSpaceName *CPrec_GetNameSpaceNamePatch(NameSpaceName *nsn, Boolean flag) { + AddrPatch *addrPatch; + NameSpaceName *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(nsn))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(nsn, first); + + do { + CPrec_AppendData(nsn, sizeof(NameSpaceName)); + CPrec_NamePatch(¤t->name, nsn->name); + CPrec_NewPointerPatch(¤t->first.object, CPrec_GetObjBasePatch(nsn->first.object)); + if (nsn->first.next) + CPrec_NewPointerPatch(¤t->first.next, CPrec_GetNameSpaceObjectListPatch(nsn->first.next)); + + if (!nsn->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(nsn->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } else { + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + nsn = nsn->next; + CPrec_NewAddrPatch(nsn, next); + } + } while (!flag || !cprec_dowrite || CPrec_FlushBufferCheck() == noErr); + + return first; +} + +static NameSpaceList *CPrec_GetNameSpaceListPatch(NameSpaceList *nsl) { + NameSpaceList *first, *current, *next; + first = current = CPrec_AppendAlign(); + + do { + CPrec_AppendData(nsl, sizeof(NameSpaceList)); + CPrec_NewPointerPatch(¤t->nspace, CPrec_GetNameSpacePatch(nsl->nspace)); + + if (!nsl->next) + break; + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + nsl = nsl->next; + } while (1); + + return first; +} + +static NameSpace *CPrec_GetNameSpacePatch(NameSpace *nspace) { + NameSpace *p; + AddrPatch *addrPatch; + + if ((addrPatch = CPrec_FindAddrPatch(nspace))) + return addrPatch->value; + + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(nspace, p); + CPrec_AppendData(nspace, sizeof(NameSpace)); + + if (nspace->parent) + CPrec_NewPointerPatch(&p->parent, CPrec_GetNameSpacePatch(nspace->parent)); + if (nspace->name) + CPrec_NamePatch(&p->name, nspace->name); + if (nspace->usings) + CPrec_NewPointerPatch(&p->usings, CPrec_GetNameSpaceListPatch(nspace->usings)); + if (nspace->theclass) + CPrec_NewPointerPatch(&p->theclass, CPrec_GetTypePatch((Type *) nspace->theclass)); + + if (nspace->is_hash) { + char *hash; + int i; + hash = CPrec_AppendAlign(); + CPrec_NewPointerPatch(&p->data.hash, hash); + CPrec_AppendData(nspace->data.hash, sizeof(NameSpaceName *) * 1024); + for (i = 0; i < 1024; i++) { + if (nspace->data.hash[i]) + CPrec_NewPointerPatch(hash + (i * sizeof(NameSpaceName *)), CPrec_GetNameSpaceNamePatch(nspace->data.hash[i], 0)); + } + } else if (nspace->data.list) { + CPrec_NewPointerPatch(&p->data.list, CPrec_GetNameSpaceNamePatch(nspace->data.list, 0)); + } + + return p; +} + +static void CPrec_DumpRootNameSpace() {} +static void CPrec_GetSOMPatch() {} +static void CPrec_GetOLinkPatch() {} +static void CPrec_GetStaticDataPatch() {} +static void CPrec_GetCallbackPatch() {} +static void CPrec_GetSelHashTablePatch() {} +static void CPrec_GetIExpressionPatch() {} +static void CPrec_GetInlineActionPatch() {} + +static void CPrec_GenerateBuiltinPatches() { + int x; + int y; + Patch *scan; + + for (x = 0; x < cprec_builtins; x++) { + y = 0; + for (scan = cprec_builtin[x].patches; scan; scan = scan->next) + ++y; + + if (y) { + CPrec_AppendWord32(y); + CPrec_AppendWord32(x); + for (scan = cprec_builtin[x].patches; scan; scan = scan->next) + CPrec_AppendWord32(scan->offset); + } + } + + CPrec_AppendWord32(0); +} + +static void CPrec_GenerateTokenStreamPatches() { + TokenPatch *scan; + + for (scan = cprec_tokenpatches; scan; scan = scan->next) { + CPrec_AppendWord32((UInt32) scan->tokens); + CPrec_AppendWord32((UInt32) scan->count); + } + CPrec_AppendWord32(0); +} + +static OSErr CPrec_CompressWrite(const char *data, SInt32 size) { + char buf[2048 + 256]; + OSErr err; + int bufpos = 0; + int blockstart; + int c; + const char *p = data; + const char *end = data + size; + + for (;;) { + if (p < end) { + if (!*p) { + c = 224; + while (!*p && p < end && c < 256) { + c++; + p++; + } + buf[bufpos++] = c - 1; + } else { + blockstart = bufpos++; + c = 0; + while (p < end && c < 224) { + if (!p[0] && !p[1]) { + break; + } else { + buf[bufpos++] = *(p++); + c++; + } + } + buf[blockstart] = c - 1; + } + } + + if (p >= end || bufpos > 2048) { + if ((err = COS_FileWrite(cprec_refnum, buf, bufpos))) + return err; + + if (p >= end) + break; + else + bufpos = 0; + } + } + + return noErr; +} + +static OSErr CPrec_FlushRawBuffer() { + OSErr err; + + if (cprec_dowrite) { + CPrec_AppendAlign(); + cprec_zero_offset += cprec_glist.size; + COS_LockHandle(cprec_glist.data); + err = CPrec_CompressWrite(*cprec_glist.data, cprec_glist.size); + COS_UnlockHandle(cprec_glist.data); + cprec_glist.size = 0; + + return err; + } else { + return noErr; + } +} + +static OSErr CPrec_FlushBufferCheck() { + static SInt32 flushmax; + OSErr err; + + if (cprec_glist.size > flushmax) + flushmax = cprec_glist.size; + + if (cprec_glist.size > 10000) { + err = CPrec_FlushRawBuffer(); + if (err) { + cprec_ioerror = err; + return err; + } + } + + return noErr; +} + +static int CPrec_CompressPatches() { + Patch *scan; + int count; + SInt32 last; + + cprec_glist.size = 0; + + scan = cprec_patch_list; + last = 0; + count = 0; + while (scan) { +#line 4339 + CError_ASSERT((scan->offset & 0x80000001) == 0); + + if ((scan->offset - last) >= -128 && (scan->offset - last) <= 126) + CPrec_AppendByte(((scan->offset - last) >> 1) | 0x80); + else + CPrec_AppendWord32(scan->offset); + + last = scan->offset; + scan = scan->next; + count++; + } + + return count; +} + +static void CPrec_DumpColorSymbolTable() {} + +static OSErr CPrec_FileAlign(short refnum, SInt32 *len) { + OSErr err; + SInt32 n; + char buf[8]; + + n = *len; + if ((n & 7) == 0) + return noErr; + + memclrw(buf, 8); + err = COS_FileWrite(refnum, buf, n = 8 - (n & 7)); + *len += n; + + return err; +} + +static void CPrec_WriteFile() {} + +void PrecompilerWrite() { +} + +static void CPrec_ReadData() {} +static void CPrec_ReadRawBuffer() {} +static void CPrec_RelocateRawBuffer() {} +static void CPrec_RelocateBuiltins() {} +static void CPrec_RelocateTokenStreams() {} +static void CPrec_RelocateMacroTable() {} +static void CPrec_RelocateTable() {} +static void CPrec_RelocateRootNameSpace() {} + +static void CPrec_FixNameIds() { + int i; + HashNameNode *node; + + for (i = 0; i < 2048; i++) { + for (node = name_hash_nodes[i]; node; node = node->next) + node->id = -1; + } +} + +static void CPrec_DefineStaticData() {} + +void PrecompilerRead(short refnum, void *buffer) { +} |