This commit is contained in:
Ash Wolf
2022-11-07 03:06:21 +00:00
parent d0b9848c54
commit 9a46dd0e2e
62 changed files with 30796 additions and 1532 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,9 @@
#include "compiler.h"
#include "compiler/CError.h"
#include "compiler/CMangler.h"
#include "compiler/CParser.h"
#include "compiler/CPrep.h"
#include "compiler/CScope.h"
#include "compiler/enode.h"
#include "compiler/objects.h"
#include "compiler/scopes.h"
@@ -1016,7 +1020,7 @@ static NameSpaceObjectList *CScope_FindLookupName(NameSpaceLookupList *list, Has
if (r6->object->otype == r30->object->otype) {
switch (r6->object->otype) {
case OT_TYPE:
if ((OBJ_TYPE(r6->object)->type == OBJ_TYPE(r30->object)->type) && (OBJ_TYPE(r6->object)->unk6 == OBJ_TYPE(r30->object)->unk6))
if ((OBJ_TYPE(r6->object)->type == OBJ_TYPE(r30->object)->type) && (OBJ_TYPE(r6->object)->qual == OBJ_TYPE(r30->object)->qual))
goto break1;
break;
case OT_TYPETAG:
@@ -1196,7 +1200,7 @@ static Boolean CScope_SetupParseNameResult(CScopeParseResult *result, NameSpaceO
return 0;
case OT_TYPE:
result->x8 = OBJ_TYPE(list->object)->type;
result->xC = OBJ_TYPE(list->object)->unk6;
result->xC = OBJ_TYPE(list->object)->qual;
result->obj_10 = list->object;
result->name_4 = name;
result->x20 = 1;
@@ -1388,7 +1392,7 @@ inline Boolean CScope_NSIteratorNext(CScopeNSIterator *iterator) {
}
}
Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, void **unk6) {
Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, UInt32 *qual) {
CScopeParseResult result;
CScopeNSIterator iterator;
NameSpaceObjectList *list;
@@ -1400,13 +1404,13 @@ Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, void **unk6) {
do {
for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) {
if (list->object->otype == OT_TYPETAG) {
if (unk6)
*unk6 = NULL;
if (qual)
*qual = 0;
return OBJ_TYPE_TAG(list->object)->type;
}
if (list->object->otype == OT_TYPE) {
if (unk6)
*unk6 = OBJ_TYPE(list->object)->unk6;
if (qual)
*qual = OBJ_TYPE(list->object)->qual;
return OBJ_TYPE(list->object)->type;
}
}
@@ -2429,7 +2433,7 @@ static void CScope_AddUsingObject(BClassList *bcl, NameSpace *nspace, ObjBase *o
if (!nspace->theclass) {
if ((list = CScope_FindQualName(nspace, name)) && (list->object->otype == OT_TYPE) &&
(OBJ_TYPE(obj)->type == OBJ_TYPE(list->object)->type) &&
(OBJ_TYPE(obj)->unk6 == OBJ_TYPE(list->object)->unk6))
(OBJ_TYPE(obj)->qual == OBJ_TYPE(list->object)->qual))
return;
}
copy = galloc(sizeof(ObjType));
@@ -2530,7 +2534,7 @@ void CScope_AddClassUsingDeclaration(TypeClass *tclass, TypeClass *tclass2, Hash
}
}
void CScope_ParseUsingDeclaration(NameSpace *nspace, AccessType access) {
void CScope_ParseUsingDeclaration(NameSpace *nspace, short access, Boolean flag) {
// almost matches, slight bit of register weirdness
CScopeParseResult result;

View File

@@ -0,0 +1,93 @@
#include "compiler/CABI.h"
#include "compiler/CMachine.h"
#include "compiler/types.h"
#include "compiler/CompilerTools.h"
static void *trans_vtboffsets; // TODO type
static void *cabi_pathroot; // TODO type - 8 byte struct??
static void *cabi_pathcur; // TODO type
static TypeClass *cabi_loop_class;
static Boolean cabi_loop_construct;
short CABI_GetStructResultArgumentIndex(void) {
return 0;
}
Type *CABI_GetSizeTType(void) {
return (Type *) &stunsignedlong;
}
Type *CABI_GetPtrDiffTType(void) {
return (Type *) &stsignedlong;
}
SInt16 CABI_StructSizeAlignValue(Type *type, SInt32 size) {}
void CABI_ReverseBitField(TypeBitfield *tbitfield) {}
// not sure about the sig for this, it's unused lmao
static void CABI_AllocateZeroVTablePointer() {}
static SInt32 CABI_GetBaseSize(TypeClass *tclass) {}
static void CABI_AllocateBases() {}
static void CABI_AllocateVirtualBasePointers() {}
static void CABI_GetMemberOffset() {}
static void CABI_AllocateMembers() {}
static void CABI_AllocateVirtualBases() {}
static void CABI_FindZeroDeltaVPtr() {}
static void CABI_FindZeroVirtualBaseMember() {}
void CABI_AddVTable(TypeClass *tclass) {
tclass->vtable = galloc(sizeof(VTable));
memclrw(tclass->vtable, sizeof(VTable));
}
SInt32 CABI_GetVTableOffset(TypeClass *tclass) {
return 0;
}
static void CABI_GetBaseVTableSize() {}
static void CABI_ApplyClassFlags() {}
static void CABI_AllocateVTable() {}
void CABI_LayoutClass(DeclE *decle, TypeClass *tclass) {}
void CABI_MakeDefaultArgConstructor(Object *obj, TypeClass *tclass) {}
static void CABI_ThisArg() {}
ENode *CABI_MakeThisExpr(TypeClass *tclass, SInt32 offset) {}
static void CABI_VArg() {}
static void CABI_MakeVArgExpr() {}
static void CABI_MakeCopyConArgExpr() {}
static void CABI_InitVBasePtr1() {}
static void CABI_InitVBasePtrs() {}
static void CABI_GetVBasePath() {}
static void CABI_GetVBasePtr() {}
static SInt32 CABI_FindNVBase(TypeClass *tclass, TypeClass *base, SInt32 offset) {}
SInt32 CABI_GetCtorOffsetOffset(TypeClass *tclass, TypeClass *base) {}
static void CABI_InitVBaseCtorOffsets() {}
static void CABI_InitVTablePtrs() {}
static Boolean CABI_IsOperatorNew(Object *obj) {}
Object *CABI_ConstructorCallsNew(TypeClass *tclass) {}
void CABI_TransConstructor(Object *obj, Statement *stmt, TypeClass *tclass, TransConstructorCallback callback, Boolean flag) {}
void CABI_MakeDefaultConstructor(TypeClass *tclass, Object *obj) {}
static void CABI_AssignObject() {}
static void CABI_FindIntegralSizeType() {}
static void CABI_AppendCopyRegion() {}
static void CABI_ClassInitLoopCallBack() {}
static void CABI_CopyConAssignCB() {}
void CABI_MakeDefaultCopyConstructor(TypeClass *tclass, Object *obj) {}
void CABI_MakeDefaultAssignmentOperator(TypeClass *tclass, Object *obj) {}
static void CABI_DestroyMembers() {}
static void CABI_DestroyBases() {}
static void CABI_DestroyVBases() {}
void CABI_TransDestructor(Object *obj1, Object *obj2, Statement *stmt, TypeClass *tclass) {}
void CABI_MakeDefaultDestructor(TypeClass *tclass, Object *obj) {}
static void CABI_CreateLayeredDestructor() {}
void CABI_MakeLayeredDestructor(TypeClass *tclass, Object *obj) {}
Object *CABI_GetDestructorObject(Object *obj, int what) {
return obj;
}
static void CABI_AddLayeredDestructor() {}
void CABI_AddLayeredDestructors(TypeClass *tclass) {}
ENode *CABI_DestroyObject(Object *dtor, ENode *objexpr, UInt8 mode, Boolean flag1, Boolean flag2) {}

View File

@@ -0,0 +1,122 @@
#include "compiler/CClass.h"
typedef struct OVClassBase {
struct OVClassBase *next;
struct OVClass *ovclass;
Boolean is_virtual;
} OVClassBase;
typedef struct OVFunc {
struct OVFunc *next;
Object *obj;
struct OVClass *ovc8;
struct OVFunc *ovfC;
struct OVFunc *ovf10;
} OVFunc;
typedef struct OVClass {
TypeClass *tclass;
OVFunc *vfuncs;
OVClassBase *bases;
SInt32 offset;
SInt32 voffset;
Boolean alloced_vtable;
} OVClass;
static TypeClass *main_class;
static void *cclass_thunklist; // TODO type
static TypeClass *cclass_isbase_mostderived;
static void *cclass_isbase_foundoffset; // TODO type
static Boolean cclass_isambigbase;
static short cclass_founddepth;
static void *vtable_object_data; // TODO type
static void *vtable_data_size; // TODO type
static VTableObjectLink *vtable_object_links;
static TypeClass *cclass_vbase;
static OVClass *cclass_ovbase;
static OVClass *cclass_root;
static Object *found_pure;
static Boolean check_pures;
static Object *cclass_dominator_vobject;
static SInt32 cclass_dominator_voffset;
static Object *cclass_dominator_oobject;
static TypeClass *cclass_dominator_oclass;
static SInt32 cclass_dominator_ooffset;
static Object *cclass_dominator_eobject;
void CClass_Init(void) {}
void CClass_GenThunks(void) {}
static Object *CClass_ThunkObject(Object *obj, SInt32 a, SInt32 b, SInt32 c) {}
static Boolean CClass_IsZeroOffsetClass(TypeClass *a, TypeClass *b) {}
static UInt8 CClass_IsCovariantResult(Type *a, UInt32 qualA, Type *b, UInt32 qualB) {}
UInt8 CClass_GetOverrideKind(TypeFunc *a, TypeFunc *b, Boolean errorflag) {}
Boolean CClass_IsEmpty(TypeClass *tclass) {}
Boolean CClass_IsNonStaticMemberFunc(TypeMethod *tmethod) {}
Object *CClass_DefaultConstructor(TypeClass *tclass) {}
Object *CClass_DummyDefaultConstructor(TypeClass *tclass) {}
ENode *CClass_DefaultConstructorCall(TypeClass *a, TypeClass *b, ENode *expr, SInt32 unkshortparam, Boolean flag1, Boolean flag2, Boolean *errorflag) {}
Object *CClass_AssignmentOperator(TypeClass *tclass) {}
Object *CClass_CopyConstructor(TypeClass *tclass) {}
NameSpaceObjectList *CClass_MemberObject(TypeClass *tclass, HashNameNode *name) {}
Object *CClass_Constructor(TypeClass *tclass) {}
Object *CClass_Destructor(TypeClass *tclass) {}
Boolean CClass_IsConstructor(Object *obj) {}
Boolean CClass_IsDestructor(Object *obj) {}
Boolean CClass_IsPODClass(TypeClass *tclass) {}
Boolean CClass_IsTrivialCopyClass(TypeClass *tclass) {}
Boolean CClass_IsTrivialCopyAssignClass(TypeClass *tclass) {}
Boolean CClass_ReferenceArgument(TypeClass *tclass) {}
BClassList *CClass_GetPathCopy(BClassList *path, Boolean is_global) {}
BClassList *CClass_AppendPath(BClassList *a, BClassList *b) {}
static AccessType CClass_GetPathAccess(BClassList *path) {}
Boolean CClass_IsMoreAccessiblePath(BClassList *path1, BClassList *path2) {}
static BClassList *CClass_GetBasePathRec(TypeClass *a, TypeClass *b, SInt32 offset, short depth) {}
BClassList *CClass_GetBasePath(TypeClass *a, TypeClass *b, short *founddepth, Boolean *isambigbase) {}
Boolean CClass_IsBaseClass(TypeClass *a, TypeClass *b, short *founddepth, Boolean pathcheckflag, Boolean ambigerrorflag) {}
TypeClass *CClass_GetQualifiedClass(void) {}
ENode *CClass_AccessPathCast(BClassList *path, ENode *expr, Boolean flag) {}
ENode *CClass_ClassPointerCast(ENode *expr, TypeClass *a, TypeClass *b, Boolean typconflag, Boolean ambigerrorflag, Boolean pathcheckflag) {}
ENode *CClass_DirectBasePointerCast(ENode *expr, TypeClass *a, TypeClass *b) {}
SInt32 CClass_GetPathOffset(BClassList *path) {}
Boolean CClass_ClassDominates(TypeClass *a, TypeClass *b) {}
SInt32 CClass_VirtualBaseOffset(TypeClass *a, TypeClass *b) {}
SInt32 CClass_VirtualBaseVTableOffset(TypeClass *a, TypeClass *b) {}
SInt32 CClass_GetMemberOffset(TypeClass *tclass, HashNameNode *name, ObjMemberVar **obj) {}
Boolean CClass_OverridesBaseMember(TypeClass *tclass, HashNameNode *name, Object *obj) {}
static OVClass *CClass_FindOVClass(OVClass *ovclass, TypeClass *tclass, SInt32 offset) {}
static OVClass *CClass_BuildOVClassTree(OVClass *root, TypeClass *tclass, SInt32 offset, SInt32 voffset) {}
static Boolean CClass_IsBaseOf(OVClass *a, OVClass *b) {}
static void CClass_FindOVFunc(OVClass *a, OVClass *b, OVFunc *func) {}
static TypeList *CClass_GetCoVariantClassList(TypeList *list, TypeClass *tclass, Object *func, Boolean flag) {}
static TypeMethod *CClass_GetCovariantType(TypeMethod *tmethod, Type *type) {}
static Object *CClass_FindCovariantFunction(Object *func, Type *type) {}
static ObjectList *CClass_DeclareCovariantFuncs(ObjectList *list, Object *func, TypeClass *tclass) {}
void CClass_DefineCovariantFuncs(Object *method, CI_FuncData *ifuncdata) {}
static void CClass_OverrideOVClassTree(OVClass *ovclass) {}
static void CClass_AllocVTableRec(OVClass *ovclass) {}
static Object *CClass_CheckClass(OVClass *ovclass, Boolean errorflag) {}
static void CClass_AllocVTable(TypeClass *tclass) {}
static Object *CClass_CheckVirtuals(TypeClass *tclass) {}
static void CClass_CheckVirtualBaseOverrides(OVClass *a, OVClass *b, Boolean flag) {}
static void CClass_CheckHideVirtual(OVClass *a, OVClass *b) {}
void CClass_CheckOverrides(TypeClass *tclass) {}
static void CClass_FindDominator(TypeClass *tclass1, SInt32 offset1, Object *object1, TypeClass *tclass2, SInt32 offset2, TypeClass *base) {}
static void CClass_ConstructVTable(TypeClass *tclass, SInt32 voffset, SInt32 offset, TypeClass *base) {}
void CClass_ClassDefaultFuncAction(TypeClass *tclass) {}
void CClass_ClassAction(TypeClass *tclass) {}
void CClass_MakeStaticActionClass(TypeClass *tclass) {}
Object *CClass_CheckPures(TypeClass *tclass) {}
void CClass_MemberDef(Object *obj, TypeClass *tclass) {}
Object *CClass_ThisSelfObject(void) {}
ENode *CClass_CreateThisSelfExpr(void) {}
static Boolean CClass_BaseMemberAccess(BClassList *path, AccessType access) {}
static Boolean CClass_CanAccess(BClassList *path, AccessType access) {}
void CClass_CheckPathAccess(BClassList *path, Object *obj, AccessType access) {}
static BClassList *CClass_PathCleanup(BClassList *path, TypeClass *tclass) {}
void CClass_CheckStaticAccess(BClassList *path, TypeClass *tclass, AccessType access) {}
void CClass_CheckObjectAccess(BClassList *path, Object *obj) {}
void CClass_CheckEnumAccess(BClassList *path, ObjEnumConst *objec) {}
static Type *CClass_PointerTypeCopy(Type *type) {}
Type *CClass_CombineClassAccessQualifiers(Type *type, UInt32 qual1, UInt32 qual2, UInt32 *outflags) {}
static void CClass_OptimizeBitFieldAccess(Type **type, SInt32 *offset) {}
ENode *CClass_AccessMember(ENode *classexpr, Type *type, UInt32 qual, SInt32 offset) {}

View File

@@ -3,6 +3,7 @@
#include "compiler/types.h"
#include "pref_structs.h"
#include "compiler/CompilerTools.h"
#include "compiler/CPrep.h"
Boolean systemHandles;
@@ -11,14 +12,6 @@ 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;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,123 @@
#include "compiler/CExpr.h"
#include "compiler/CError.h"
Boolean (*name_obj_check)(void *, Object *); // TODO figure out the right type
Boolean disallowgreaterthan;
void CExpr_RewriteConst() {}
void optimizecomm() {}
static void checkadditive() {}
static void CExpr_CompareConvert() {}
static void CExpr_ConstResult() {}
static void makemultnode() {}
static void makedivnode() {}
static void canadd2() {}
void canadd() {}
static void addconst() {}
static void integralpointerpromote() {}
static void padd() {}
static void psub() {}
static void makeaddnode() {}
static void makesubnode() {}
void checkreference() {}
static ENode *pointer_generation2(ENode *expr) {}
ENode *pointer_generation(ENode *expr) {}
void CExpr_PointerGeneration() {}
static void CExpr_ConstPointerCheck() {}
void oldassignmentpromotion() {}
void argumentpromotion() {}
void classargument() {}
ENodeList *CExpr_ScanExpressionList(Boolean flag) {}
static void skipcommaexpr() {}
void CExpr_DoExplicitConversion() {}
static void CExpr_TemplArgDepCast() {}
static void CExpr_ParseExplicitConversion() {}
static void CExpr_MemberVarAccess() {}
static void CExpr_IsTemplateFunc() {}
static void CExpr_ExplicitTemplateArgCheck() {}
void CExpr_MakeNameLookupResultExpr() {}
static void CExpr_NewPTMType() {}
static void CExpr_ParseNameResultExpr() {}
static void CExpr_ParseRotate() {}
static void CExpr_ParseNextArg() {}
static void CExpr_ParseVecStep() {}
static void CExpr_BuiltInComputeAlign() {}
static void CExpr_AtomTypeID() {}
static void CExpr_BuiltInComputeType() {}
static void CExpr_BuiltInClassifyType() {}
static void CExpr_BuiltInComputeVArgType() {}
static void CExpr_ParseTypeExpression() {}
static void CExpr_ParseBuiltin() {}
static void CExpr_ParseBuiltin_isintconst() {}
static void primary_expression() {}
static void CExpr_SimpleExplicitConversion() {}
static void CExpr_NewPTMFCall() {}
static void call_ptmf() {}
static void CExpr_DummyDestr() {}
static void postfix_expression() {}
static void CExpr_ParseSizeof() {}
void scansizeof() {}
static void CExpr_ParseAlignof() {}
void scanalignof() {}
static void logicalexpression() {}
void getnodeaddress() {}
static void CExpr_MakeStaticMemberList() {}
static void CExpr_MakePTDM() {}
void getpointertomemberfunc() {}
static void getpointertomember() {}
void CExpr_New_ELOGNOT_Node() {}
void CExpr_New_EMONMIN_Node() {}
void CExpr_New_EBINNOT_Node() {}
void unary_expression() {}
void do_castnullcheck() {}
void CExpr_SafeClassPointerCast() {}
void PointerToMemberCast() {}
void CExpr_MemberPointerConversion() {}
static void CExpr_MemberPointerCast() {}
void do_typecast() {}
static void isvectorconst() {}
void cast_expression() {}
static void pm_expression() {}
void CExpr_New_EMUL_Node() {}
void CExpr_New_EDIV_Node() {}
void CExpr_New_EMODULO_Node() {}
void CExpr_New_EADD_Node() {}
void CExpr_New_ESUB_Node() {}
void CExpr_New_ESHL_Node() {}
void CExpr_New_ESHR_Node() {}
static void pointercompare() {}
static void unsigncheck() {}
void CExpr_New_ELESS_Node() {}
void CExpr_New_ELESSEQU_Node() {}
void CExpr_New_EGREATER_Node() {}
void CExpr_New_EGREATEREQU_Node() {}
void memberpointercompare() {}
void CExpr_New_EEQU_Node() {}
void CExpr_New_ENOTEQU_Node() {}
void CExpr_New_EAND_Node() {}
void CExpr_New_EXOR_Node() {}
void CExpr_New_EOR_Node() {}
void CExpr_New_ELAND_Node() {}
void CExpr_New_ELOR_Node() {}
void CExpr_NewDyadicNode() {}
static void CExpr_GetDyadicInfo() {}
static void CExpr_ParseDyadicExpression() {}
static void CExpr_IsBlockMoveType() {}
void CExpr_New_ECOND_Node() {}
static void conditional_expression() {}
static void CExpr_MakeOpAssNode() {}
static void makeassignmentnode() {}
static void makepassignmentnode() {}
static void makemulassignmentnode() {}
static void CExpr_TransformOpAssign() {}
ENode *assignment_expression(void) {}
ENode *conv_assignment_expression(void) {}
static void CExpr_HasSideEffect() {}
void CExpr_CheckUnusedExpression() {}
void s_expression() {}
ENode *expression(void) {}
void CExpr_IntegralConstExprType() {}
ENode *CExpr_IntegralConstOrDepExpr(void) {}
void CExpr_IntegralConstExpr() {}
void CExpr_CheckUnwantedAssignment() {}
void CExpr_ParseAsmExpr() {}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,105 @@
#include "compiler/CFunc.h"
#include "compiler/types.h"
FuncArg elipsis;
FuncArg oldstyle;
ObjectList *arguments;
ObjectList *locals;
short localcount;
SInt32 curstmtvalue;
SInt32 sourceoffset;
HashNameNode *sourcefilepath;
SInt32 functionbodyoffset;
HashNameNode *functionbodypath;
InitExpr *init_expressions;
CLabel *Labels;
CtorChain *ctor_chain;
Statement *curstmt;
static short temp_destructor_object_regmem;
static short temp_destructor_objects;
static short temp_expression_has_conditionals;
static DeclBlock *firstblock;
static DeclBlock *currentblock;
static short blockcount;
static Object *sinit_first_object;
static CLabel *sinit_label;
static Boolean ainit_only_one;
static ENode *ainit_expr;
static FuncArg *check_arglist;
static Boolean cfunc_is_extern_c;
static short cfunc_staticvarcount;
static void *destroyobjects;
static Boolean cfunc_hasdtortemp;
static void CFunc_LoopIncrement(void) {}
static void CFunc_LoopDecrement(void) {}
DeclBlock *CFunc_NewDeclBlock(void) {}
void CFunc_RestoreBlock(DeclBlock *block) {}
void CFunc_SetupLocalVarInfo(Object *obj) {}
static void adjustargumenttype(DeclInfo *declinfo) {}
static FuncArg *CFunc_IsInArgList(FuncArg *list, HashNameNode *name) {}
static Object *CFunc_IsInObjList(ObjectList *list, HashNameNode *name) {}
static void CFunc_AppendArg(FuncArg **list, FuncArg *arg) {}
static void identifier_list(DeclInfo *declinfo) {}
static Boolean defarg_name_obj_check(HashNameNode *name, Object *obj) {}
void CFunc_DefaultArg(Type *type, short qual, FuncArg *args) {}
static FuncArg *parameter_list(DeclInfo *declinfo) {}
Boolean CFunc_ParseFakeArgList(Boolean flag) {}
FuncArg *parameter_type_list(DeclInfo *declinfo) {}
CLabel *findlabel(void) {}
CLabel *newlabel(void) {}
Statement *CFunc_AppendStatement(StatementType sttype) {}
Statement *CFunc_InsertStatement(StatementType sttype, Statement *after) {}
Statement *CFunc_InsertBeforeStatement(StatementType sttype, Statement *before) {}
void CheckCLabels(void) {}
Object *create_temp_object(Type *type) {}
ENode *create_temp_node(Type *type) {}
ENode *create_temp_node2(Type *type) {}
static void CFunc_DestroyReverse() {} // not sure about type
static void CFunc_TempTransDestroy() {} // not sure about type
void CFunc_WarnUnused(void) {}
void CFunc_CodeCleanup(Statement *stmt) {}
static Boolean DestructorNeeded(ExceptionAction *a, ExceptionAction *b) {}
static Statement *DestructLocals(Statement *stmt, ExceptionAction *exc1, ExceptionAction *exc2) {}
static Boolean NeedsDestruction(Statement *stmt1, Statement *stmt2) {}
static ExceptionAction *FindLastNonCommonStackObj(Statement *stmt1, Statement *stmt2) {}
static void DestructorReturnTransform(Statement *stmt1, Statement *stmt2) {}
static Statement *DestructorIfTransform(Statement *stmt) {}
static Boolean IsSubStack(ExceptionAction *exc1, ExceptionAction *exc2) {}
static void CFunc_CheckInitSkip(Statement *stmt, ExceptionAction *exc) {}
void CFunc_DestructorCleanup(Statement *stmt) {}
static void scancase(DeclThing *thing) {}
static void CFunc_NameLocalStaticDataObject(Object *obj, char *str) {}
static void sinit_insert_expr(ENode *expr) {}
static void ainit_insert_expr(ENode *expr) {}
static ENode *ainit_register_object(TypeClass *tclass, Object *local, SInt32 offset, void *unk) {}
static void CFunc_LocalDataDeclarator(DeclInfo *declinfo, TStreamElement *element, Boolean flag1, Boolean flag2) {}
static ENode *CFunc_ParseLocalDeclarationList(Boolean flag1, Boolean flag2, Boolean flag3, Boolean flag4) {}
static void makeifstatement(ENode *expr, CLabel *label1, CLabel *label2, Boolean flag1, Boolean flag2) {}
static void CFunc_HasDtorTempCallBack(ENode *expr) {}
static void ifstatement(Boolean flag1, ENode *expr, CLabel *label, Boolean flag2) {}
Statement *CFunc_GenerateLoop(Statement *stmt, Type *type, ENode *expr1, ENode *expr2, ENode *expr3, ENode *expr4, ENode (*callback)(ENode *, ENode *)) {}
static Boolean checklabel(void) {}
static ENode *returnstatementadjust(ENode *expr, Type *type, UInt32 qual) {}
static void CFunc_AutoResultCheck(ENode *expr) {}
static void statement(DeclThing *thing) {}
void CFunc_CompoundStatement(DeclThing *thing) {}
static void CFunc_InsertArgumentCopyConversion(Object *obj, Type *type1, Type *type2, Boolean flag) {}
static void CFunc_AdjustOldStyleArgs(void) {}
void CFunc_SetupNewFuncArgs(Object *obj, FuncArg *args) {}
static ObjectList *CFunc_CopyObjectList(ObjectList *list) {}
static void SetupFunctionArguments(Object *obj, DeclInfo *declinfo) {}
NameSpace *CFunc_FuncGenSetup(Statement *stmt) {}
void CFunc_GetGlobalCompilerState(CFuncSave *state) {}
void CFunc_SetGlobalCompilerState(CFuncSave *state) {}
void CFunc_Gen(Statement *stmt, Object *obj, UInt8 unk) {}
static void CFunc_CheckCtorInitializer(TypeClass *tclass, CtorChain *chain) {}
void CFunc_CheckClassCtors(TypeClass *tclass) {}
static void CFunc_ParseCtorInitializer(void) {}
static void CFunc_FunctionRedefinedCheck(Object *obj) {}
static Object *CFunc_DeclareFuncName(char *str, HashNameNode *name) {}
void CFunc_ParseFuncDef(Object *obj, DeclInfo *declinfo, TypeClass *tclass, Boolean is_method, Boolean is_static, NameSpace *nspace) {}
void InitExpr_Register(ENode *expr, Object *object) {}
void CFunc_GenerateDummyFunction(Object *a) {}
void CFunc_GenerateSingleExprFunc(Object *a, ENode *expr) {}
void CFunc_GenerateDummyCtorFunc(Object *a, Object *b) {}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,116 @@
#include "compiler/CInline.h"
#include "compiler/CFunc.h"
static CInlineCopyMode enode_copymode;
static Boolean enode_globalcopy;
static void *enode_idtrans; // type?
static void *local_dobjects; // type?
static void *local_aobjects; // type?
static CI_Var *loc_args;
static CI_Var *loc_vars;
static Boolean inline_expanded;
static Boolean any_inline_expanded;
static short cinline_level;
static void *cinline_label_trans; // type?
static Statement *cinline_first_stmt;
static void *cinline_stmtlevelexpr[16]; // type?
static short cinline_stmtlevelexprs;
static Boolean cinline_unconditionalpart;
static Boolean cinline_serialize_stmt;
static void *cinline_exportlist; // type?
static CI_Action *cinline_actionlist;
CI_Action *cinline_tactionlist;
static ObjectList *cinline_freflist;
static Boolean cinline_gendeps;
static Statement *cinline_serial_stmt;
static Statement *cinline_cur_serial_stmt;
static void *cinline_uid_temps; // type?
static Boolean cinline_has_sideeffect;
static SInt32 inline_max_size;
static Boolean recursive_inline;
static Object *expanding_function;
static Boolean cinline_funccallfound;
void CInline_Init(void) {}
static ENode *CInline_MakeNotNot(ENode *expr) {}
static ENode *CInline_FoldConst(ENode *expr) {}
SInt32 CInline_GetLocalID(Object *obj) {}
static Boolean CInline_IsTrivialExpression(ENode *expr) {}
Boolean CInline_ExpressionHasSideEffect(ENode *expr) {}
static ENode *CInline_CopyExpressionSave(ENode *expr) {}
static SInt32 CInline_TranslateID(SInt32 id) {}
static SInt32 CInline_GetLabelStatementNumber(HashNameNode *name) {}
static ENodeList *CInline_CopyNodeList(ENodeList *list) {}
static EMemberInfo *CInline_CopyEMemberInfo(EMemberInfo *mi) {}
static ENode *CInline_CopyNodes(ENode *node) {}
static void CInline_CheckUsage(ENode *expr, Boolean flag) {}
ENode *CInline_CopyExpression(ENode *expr, CInlineCopyMode mode) {}
static UInt8 CInline_GetObjectSFlags(Object *obj) {}
static void CInline_SetObjectSFlags(Object *obj, UInt8 sflags) {}
static Object *CInline_NewLocalObject(Type *type, short qual, UInt8 sflags) {}
static ENode *CInline_FuncArgConvert(ENode *expr) {}
static ENode *CInline_RefArgTransform(ENode *expr, Boolean flag) {}
static ENode *CInline_SetupArgsExpression(Object *obj, CI_FuncData *data, ENodeList *list) {}
static void CInline_ReturnCheckCB(/* there should be args here */) {}
static ENode *CInline_ReturnCheck(ENode *expr) {}
static ENode *CInline_ReturnMemResult(void) {}
static ENode *CInline_InlineFunctionExpression(ENode *expr) {}
static Boolean CInline_CanExpand(ENode *expr) {}
static SInt32 CInline_EstimateSizeOfExpr(ENode *expr, SInt32 a, SInt32 b) {}
static SInt32 CInline_EstimateSizeOfFunc(CI_FuncData *funcdata, SInt32 a, SInt32 b) {}
static SInt32 EstimateExpandedSizeOfExpr(ENode *expr, SInt32 b) {}
static SInt32 EstimateExpandedSizeOfFunction(Statement *stmt) {}
static Boolean CInline_InlineFunctionCheck(ENode *expr) {}
static ENode *CInline_ExpandExpression(ENode *expr) {}
static Statement *CInline_NewStatement(StatementType sttype) {}
static ENode *CInline_LoadToTemp(ENode *expr, Object **obj) {}
static ENode *CInline_SerializeEFORCELOAD(ENode *expr) {}
static ENode *CInline_SerializeECOMMA(ENode *expr) {}
static ENode *CInline_SerializeELOR(ENode *expr) {}
static ENode *CInline_SerializeELAND(ENode *expr) {}
static ENode *CInline_SerializeEPRECOMP(ENode *expr) {}
static ENode *CInline_SerializeENULLCHECK(ENode *expr) {}
static ENode *CInline_SerializeECOND(ENode *expr) {}
static ENode *CInline_SerializeExpr(ENode *expr) {}
void CInline_SerializeStatement(Statement *stmt) {}
static void CInline_UnpackSwitch(Statement *stmt, CI_Statement *packed, CLabel **labels) {}
Object *CInline_GetLocalObj(SInt32 id, Boolean flag) {}
static ExceptionAction *CInline_UnpackActions(CI_Statement *packed, Boolean flag) {}
static Statement *CInline_ExpandStatements(Object *obj, Statement *stmt, CI_FuncData *data, ENode *expr, CLabel *label, Object *obj2, Boolean flag) {}
static Statement *CInline_InlineFunctionStatement(Statement *stmt, Boolean *success) {}
static Statement *CInline_ExtractInlineFunction(Statement *stmt) {}
static Statement *CInline_ExpandStatement(Statement *stmt) {}
static void CInline_ForceReverseSearch(ENode *) {}
static ENode *CInline_ForceReverseEvaluation(ENode *expr) {}
static void CInline_ExportCheck(ENode *expr) {}
static void CInline_Expand(Statement *stmt) {}
SInt32 CInline_GetStatementNumber(Statement *first, Statement *stmt) {}
static CI_Switch *CInline_PackSwitch(Statement *s1, Statement *s2) {}
static Boolean CInline_CanInline(Object *obj, Statement *stmt) {}
static ExceptionAction *CInline_PackActions(Statement *s1, Statement *s2) {}
void CInline_PackIFunctionData(CI_FuncData *packed, Statement *stmt, Object *obj) {}
void CInline_UnpackIFunctionData(Object *obj, CI_FuncData *packed, Statement *stmt) {}
static void CInline_GenIFunctionCode(Object *obj, CI_FuncData *func, UInt8 unk) {}
void CInline_AddDefaultFunctionAction(Object *obj) {}
void CInline_AddInlineFunctionAction(Object *obj, TypeClass *tclass, FileOffsetInfo *fileoffset, TStream *stream, Boolean flag) {}
void CInline_AddMemberFunctionAction(Object *obj, Type *a, Type *b, TemplateMember *tmemb) {}
void CInline_AddTemplateFunctionAction(Object *obj, TemplateFunction *func, TemplFuncInstance *inst) {}
static void CInline_AddFRefList_Object(Object *obj) {}
static void CInline_AddFRefList_ExAction(ExceptionAction *exc) {}
static void CInline_AddFRefList_ExprCB(ENode *expr) {}
static void CInline_AddFRefList_Expr(ENode *expr) {}
static void CInline_AddFRefList_Statement(Statement *stmt) {}
static void CInline_AddFRefList_InlineFunc(CI_FuncData *data) {}
static void CInline_GenerateTemplateInline(Object *obj) {}
void CInline_ObjectAddrRef(Object *obj) {}
static Boolean CInline_CheckDependencies(ObjectList *list) {}
static Boolean CInline_IsSmallFunction(Object *obj, Statement *stmt) {}
static Boolean CInline_NoFPLocals(void) {}
void CInline_GenFunc(Statement *stmt, Object *obj, UInt8 unk) {}
static void CInline_GenerateDefaultFunc(Object *obj) {}
static TemplClassInst *CInline_FindNestedTemplInst(TemplClassInst *inst) {}
static void CInline_GenerateInlineFunc(CI_Action *action) {}
Boolean CInline_CanFreeLHeap(void) {}
Boolean CInline_GenerateDeferredFuncs(void) {}
static InitExpr *CInline_InitTemplateData(InitExpr *init) {}
void CInline_Finish(void) {}

View File

@@ -186,6 +186,7 @@ SInt32 CMach_ArgumentAlignment(Type *type) {
return align;
}
// TODO: investigate if this returns SInt16 actually
SInt32 CMach_AllocationAlignment(Type *type, UInt32 qual) {
SInt32 align;
SInt32 qualalign;
@@ -573,7 +574,7 @@ void CMach_InitIntMem(Type *type, CInt64 val, void *mem) {
}
}
void CMach_InitVectorMem(Type *type, MWVector128 val, void *mem) {
void CMach_InitVectorMem(Type *type, MWVector128 val, void *mem, Boolean flag) {
unsigned char uc[16];
unsigned short us[8];
unsigned int ul[4];
@@ -856,7 +857,7 @@ static SInt16 CMach_GetQualifiedStructAlign(TypeStruct *tstruct, Boolean flag) {
switch (copts.align_mode) {
case AlignMode3_1Byte:
case AlignMode8:
case AlignMode8_Packed:
return 1;
case AlignMode0_Mac68k:
return 2;
@@ -941,7 +942,7 @@ static SInt16 CMach_GetQualifiedClassAlign(TypeClass *tclass, Boolean flag) {
switch (copts.align_mode) {
case AlignMode3_1Byte:
case AlignMode8:
case AlignMode8_Packed:
return 1;
case AlignMode0_Mac68k:
return 2;
@@ -1047,7 +1048,7 @@ static SInt16 CMach_GetQualifiedTypeAlign(Type *type, Boolean flag) {
switch (copts.align_mode) {
case AlignMode3_1Byte:
case AlignMode8:
case AlignMode8_Packed:
return 1;
case AlignMode4_2Byte:
case AlignMode5_4Byte:
@@ -1166,7 +1167,7 @@ static SInt16 CMach_GetMemberAlignment(Type *type, SInt32 var, Boolean flag) {
align = 16;
switch (copts.align_mode) {
case AlignMode8:
case AlignMode8_Packed:
align = 1;
break;
case AlignMode0_Mac68k:
@@ -1266,7 +1267,7 @@ SInt32 CMach_StructLayoutBitfield(TypeBitfield *tbitfield, UInt32 qual) {
switch (copts.align_mode) {
case AlignMode3_1Byte:
case AlignMode8:
case AlignMode8_Packed:
required_alignment = 0;
break;
}

View File

@@ -0,0 +1,719 @@
#include "compiler.h"
#include "compiler/CError.h"
#include "compiler/CInt64.h"
#include "compiler/enode.h"
#include "compiler/objects.h"
#include "compiler/scopes.h"
#include "compiler/templates.h"
#include "compiler/types.h"
#include "cos.h"
HashNameNode *constructor_name_node;
HashNameNode *destructor_name_node;
HashNameNode *asop_name_node;
// forward decls
static void CMangler_MangleClassName(TypeClass *tclass);
static void CMangler_MangleTypeAppend(Type *type, UInt32 qual);
static void CMangler_MangleArgs(FuncArg *args);
void CMangler_Setup(void) {
constructor_name_node = GetHashNameNodeExport("__ct");
destructor_name_node = GetHashNameNodeExport("__dt");
asop_name_node = GetHashNameNodeExport("__as");
}
HashNameNode *CMangler_BasicDtorName(void) {
return GetHashNameNodeExport("__dtb");
}
HashNameNode *CMangler_VBaseDtorName(void) {
return GetHashNameNodeExport("__dtv");
}
HashNameNode *CMangler_ArrayDtorName(void) {
return GetHashNameNodeExport("__dta");
}
HashNameNode *CMangler_SDeleteDtorName(void) {
return GetHashNameNodeExport("__dts");
}
HashNameNode *CMangler_DeleteDtorName(void) {
return GetHashNameNodeExport("__dt");
}
char *CMangler_GetOperator(HashNameNode *opname) {
char *name;
if (opname == asop_name_node)
return "operator=";
name = opname->name;
if (!strcmp(name, "__nw")) return "operator new";
if (!strcmp(name, "__dl")) return "operator delete";
if (!strcmp(name, "__nwa")) return "operator new[]";
if (!strcmp(name, "__dla")) return "operator delete[]";
if (!strcmp(name, "__pl")) return "operator+";
if (!strcmp(name, "__mi")) return "operator-";
if (!strcmp(name, "__ml")) return "operator*";
if (!strcmp(name, "__dv")) return "operator/";
if (!strcmp(name, "__md")) return "operator%";
if (!strcmp(name, "__er")) return "operator^";
if (!strcmp(name, "__ad")) return "operator&";
if (!strcmp(name, "__or")) return "operator|";
if (!strcmp(name, "__co")) return "operator~";
if (!strcmp(name, "__nt")) return "operator!";
if (!strcmp(name, "__lt")) return "operator<";
if (!strcmp(name, "__gt")) return "operator>";
if (!strcmp(name, "__apl")) return "operator+=";
if (!strcmp(name, "__ami")) return "operator-=";
if (!strcmp(name, "__amu")) return "operator*=";
if (!strcmp(name, "__adv")) return "operator/=";
if (!strcmp(name, "__amd")) return "operator%=";
if (!strcmp(name, "__aer")) return "operator^=";
if (!strcmp(name, "__aad")) return "operator&=";
if (!strcmp(name, "__aor")) return "operator|=";
if (!strcmp(name, "__ls")) return "operator<<";
if (!strcmp(name, "__rs")) return "operator>>";
if (!strcmp(name, "__als")) return "operator<<=";
if (!strcmp(name, "__ars")) return "operator>>=";
if (!strcmp(name, "__eq")) return "operator==";
if (!strcmp(name, "__ne")) return "operator!=";
if (!strcmp(name, "__le")) return "operator<=";
if (!strcmp(name, "__ge")) return "operator>=";
if (!strcmp(name, "__aa")) return "operator&&";
if (!strcmp(name, "__oo")) return "operator||";
if (!strcmp(name, "__pp")) return "operator++";
if (!strcmp(name, "__mm")) return "operator--";
if (!strcmp(name, "__cm")) return "operator,";
if (!strcmp(name, "__rm")) return "operator->*";
if (!strcmp(name, "__rf")) return "operator*";
if (!strcmp(name, "__cl")) return "operator()";
if (!strcmp(name, "__vc")) return "operator[]";
return NULL;
}
HashNameNode *CMangler_OperatorName(short token) {
switch (token) {
case TK_NEW: return GetHashNameNodeExport("__nw");
case TK_DELETE: return GetHashNameNodeExport("__dl");
case TK_NEW_ARRAY: return GetHashNameNodeExport("__nwa");
case TK_DELETE_ARRAY: return GetHashNameNodeExport("__dla");
case '+': return GetHashNameNodeExport("__pl");
case '-': return GetHashNameNodeExport("__mi");
case '*': return GetHashNameNodeExport("__ml");
case '/': return GetHashNameNodeExport("__dv");
case '%': return GetHashNameNodeExport("__md");
case '^': return GetHashNameNodeExport("__er");
case '&': return GetHashNameNodeExport("__ad");
case '|': return GetHashNameNodeExport("__or");
case '~': return GetHashNameNodeExport("__co");
case '!': return GetHashNameNodeExport("__nt");
case '=': return asop_name_node;
case '<': return GetHashNameNodeExport("__lt");
case '>': return GetHashNameNodeExport("__gt");
case TK_ADD_ASSIGN: return GetHashNameNodeExport("__apl");
case TK_SUB_ASSIGN: return GetHashNameNodeExport("__ami");
case TK_MULT_ASSIGN: return GetHashNameNodeExport("__amu");
case TK_DIV_ASSIGN: return GetHashNameNodeExport("__adv");
case TK_MOD_ASSIGN: return GetHashNameNodeExport("__amd");
case TK_XOR_ASSIGN: return GetHashNameNodeExport("__aer");
case TK_AND_ASSIGN: return GetHashNameNodeExport("__aad");
case TK_OR_ASSIGN: return GetHashNameNodeExport("__aor");
case TK_SHL: return GetHashNameNodeExport("__ls");
case TK_SHR: return GetHashNameNodeExport("__rs");
case TK_SHL_ASSIGN: return GetHashNameNodeExport("__als");
case TK_SHR_ASSIGN: return GetHashNameNodeExport("__ars");
case TK_LOGICAL_EQ: return GetHashNameNodeExport("__eq");
case TK_LOGICAL_NE: return GetHashNameNodeExport("__ne");
case TK_LESS_EQUAL: return GetHashNameNodeExport("__le");
case TK_GREATER_EQUAL: return GetHashNameNodeExport("__ge");
case TK_LOGICAL_AND: return GetHashNameNodeExport("__aa");
case TK_LOGICAL_OR: return GetHashNameNodeExport("__oo");
case TK_INCREMENT: return GetHashNameNodeExport("__pp");
case TK_DECREMENT: return GetHashNameNodeExport("__mm");
case ',': return GetHashNameNodeExport("__cm");
case TK_ARROW_STAR: return GetHashNameNodeExport("__rm");
case TK_ARROW: return GetHashNameNodeExport("__rf");
case '(': return GetHashNameNodeExport("__cl");
case '[': return GetHashNameNodeExport("__vc");
default: return NULL;
}
}
HashNameNode *CMangler_VTableName(TypeClass *tclass) {
HashNameNode *name;
name_mangle_list.size = 0;
AppendGListName(&name_mangle_list, "__vt__");
CMangler_MangleClassName(tclass);
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
HashNameNode *CMangler_RTTIObjectName(Type *type, UInt32 qual) {
HashNameNode *name;
name_mangle_list.size = 0;
AppendGListName(&name_mangle_list, "__RTTI__");
CMangler_MangleTypeAppend(type, qual);
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
HashNameNode *CMangler_ThunkName(Object *obj, int a, int b, int c) {
HashNameNode *linkname;
HashNameNode *name;
char buf[64];
linkname = CMangler_GetLinkName(obj);
name_mangle_list.size = 0;
if (b == 0) {
if (c < 0)
sprintf(buf, "_@%ld@", -a);
else
sprintf(buf, "_@%ld@%ld@", -a, c);
} else {
sprintf(buf, "_@%ld@%ld@%ld@", -a, c, b);
}
AppendGListName(&name_mangle_list, buf);
AppendGListID(&name_mangle_list, linkname->name + 1);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
static void CMangler_CheckTemplateArguments(TemplArg *arg) {
ENode *expr;
while (arg) {
if (arg->pid.type == TPT_NONTYPE) {
expr = arg->data.paramdecl.expr;
#line 360
CError_ASSERT(expr);
if (expr->rtype->type != TYPETEMPLDEPEXPR) {
switch (expr->type) {
case EINTCONST:
break;
case EOBJREF:
CMangler_GetLinkName(expr->data.objref);
break;
default:
#line 383
CError_FATAL();
}
}
}
arg = arg->next;
}
}
static void CMangler_AppendTemplateArgumentList(TemplArg *arg) {
ENode *expr;
char buf[32];
AppendGListByte(&name_mangle_list, '<');
while (arg) {
if (arg->pid.type == TPT_NONTYPE) {
expr = arg->data.paramdecl.expr;
#line 409
CError_ASSERT(expr);
if (expr->rtype->type != TYPETEMPLDEPEXPR) {
switch (expr->type) {
case EINTCONST:
CInt64_PrintDec(buf, expr->data.intval);
AppendGListName(&name_mangle_list, buf);
break;
case EOBJREF:
AppendGListByte(&name_mangle_list, '&');
AppendGListName(&name_mangle_list, CMangler_GetLinkName(expr->data.objref)->name);
break;
default:
#line 452
CError_FATAL();
}
} else {
AppendGListByte(&name_mangle_list, 'T');
}
} else if (arg->pid.type == TPT_TYPE) {
CMangler_MangleTypeAppend(arg->data.typeparam.type, arg->data.typeparam.qual);
} else {
#line 467
CError_ASSERT(arg->pid.type == TPT_TEMPLATE);
CMangler_MangleTypeAppend(arg->data.ttargtype, 0);
}
if (arg->next)
AppendGListByte(&name_mangle_list, ',');
arg = arg->next;
}
AppendGListByte(&name_mangle_list, '>');
}
HashNameNode *CMangler_TemplateInstanceName(HashNameNode *basename, TemplArg *args) {
HashNameNode *name;
CMangler_CheckTemplateArguments(args);
name_mangle_list.size = 0;
AppendGListName(&name_mangle_list, basename->name);
CMangler_AppendTemplateArgumentList(args);
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
static void CMangler_MangleTypeName(char *str) {
char buf[16];
sprintf(buf, "%d", strlen(str));
AppendGListName(&name_mangle_list, buf);
AppendGListName(&name_mangle_list, str);
}
static void CMangler_MangleNameSpaceName(NameSpace *nspace, char *str) {
char *stack[10];
int stackp;
stack[0] = str;
stackp = 1;
while (nspace) {
if (nspace->name) {
stack[stackp++] = nspace->name->name;
if (stackp >= 9)
break;
}
nspace = nspace->parent;
}
if (stackp > 1) {
AppendGListByte(&name_mangle_list, 'Q');
AppendGListByte(&name_mangle_list, '0' + stackp);
}
while (--stackp >= 0)
CMangler_MangleTypeName(stack[stackp]);
}
static void CMangler_MangleClassName(TypeClass *tclass) {
if (!tclass->classname)
CMangler_MangleNameSpaceName(tclass->nspace->parent, "class");
else
CMangler_MangleNameSpaceName(tclass->nspace->parent, tclass->nspace->name->name);
}
static void CMangler_MangleQualifier(UInt32 qual) {
if (qual & Q_CONST)
AppendGListByte(&name_mangle_list, 'C');
if (qual & Q_VOLATILE)
AppendGListByte(&name_mangle_list, 'V');
}
static void CMangler_MangleTypeAppend(Type *type, UInt32 qual) {
char buf[16];
switch (type->type) {
case TYPEVOID:
CMangler_MangleQualifier(qual);
AppendGListByte(&name_mangle_list, 'v');
break;
case TYPEINT:
case TYPEFLOAT:
CMangler_MangleQualifier(qual);
switch (TYPE_INTEGRAL(type)->integral) {
case IT_BOOL:
AppendGListByte(&name_mangle_list, 'b');
return;
case IT_CHAR:
AppendGListByte(&name_mangle_list, 'c');
return;
case IT_WCHAR_T:
AppendGListByte(&name_mangle_list, 'w');
return;
case IT_UCHAR:
AppendGListName(&name_mangle_list, "Uc");
return;
case IT_SCHAR:
AppendGListName(&name_mangle_list, "Sc");
return;
case IT_SHORT:
AppendGListByte(&name_mangle_list, 's');
return;
case IT_USHORT:
AppendGListName(&name_mangle_list, "Us");
return;
case IT_INT:
AppendGListByte(&name_mangle_list, 'i');
return;
case IT_UINT:
AppendGListName(&name_mangle_list, "Ui");
return;
case IT_LONG:
AppendGListByte(&name_mangle_list, 'l');
return;
case IT_ULONG:
AppendGListName(&name_mangle_list, "Ul");
return;
case IT_LONGLONG:
AppendGListByte(&name_mangle_list, 'x');
return;
case IT_ULONGLONG:
AppendGListName(&name_mangle_list, "Ux");
return;
case IT_FLOAT:
AppendGListByte(&name_mangle_list, 'f');
return;
case IT_SHORTDOUBLE:
AppendGListByte(&name_mangle_list, 'D');
return;
case IT_DOUBLE:
AppendGListByte(&name_mangle_list, 'd');
return;
case IT_LONGDOUBLE:
AppendGListByte(&name_mangle_list, 'r');
return;
default:
#line 619
CError_FATAL();
}
case TYPEENUM:
CMangler_MangleQualifier(qual);
if (!TYPE_ENUM(type)->enumname)
CMangler_MangleNameSpaceName(TYPE_ENUM(type)->nspace, "enum");
else
CMangler_MangleNameSpaceName(TYPE_ENUM(type)->nspace, TYPE_ENUM(type)->enumname->name);
break;
case TYPEPOINTER:
CMangler_MangleQualifier(TYPE_POINTER(type)->qual);
if (TYPE_POINTER(type)->qual & Q_REFERENCE)
AppendGListByte(&name_mangle_list, 'R');
else
AppendGListByte(&name_mangle_list, 'P');
CMangler_MangleTypeAppend(TYPE_POINTER(type)->target, qual);
break;
case TYPEMEMBERPOINTER:
if (TYPE_MEMBER_POINTER(type)->ty2->type != TYPECLASS) {
AppendGListName(&name_mangle_list, "3<T>");
} else {
CMangler_MangleQualifier(TYPE_MEMBER_POINTER(type)->qual);
AppendGListByte(&name_mangle_list, 'M');
CMangler_MangleClassName(TYPE_CLASS(TYPE_MEMBER_POINTER(type)->ty2));
CMangler_MangleTypeAppend(TYPE_MEMBER_POINTER(type)->ty1, qual);
}
break;
case TYPEARRAY:
AppendGListByte(&name_mangle_list, 'A');
if (TYPE_POINTER(type)->target->size) {
sprintf(buf, "%ld", type->size / TYPE_POINTER(type)->target->size);
AppendGListName(&name_mangle_list, buf);
} else {
AppendGListByte(&name_mangle_list, '0');
}
AppendGListByte(&name_mangle_list, '_');
CMangler_MangleTypeAppend(TYPE_POINTER(type)->target, qual);
break;
case TYPEFUNC:
CMangler_MangleQualifier(qual);
AppendGListByte(&name_mangle_list, 'F');
CMangler_MangleArgs(TYPE_FUNC(type)->args);
AppendGListByte(&name_mangle_list, '_');
CMangler_MangleTypeAppend(TYPE_FUNC(type)->functype, TYPE_FUNC(type)->qual);
break;
case TYPESTRUCT:
CMangler_MangleQualifier(qual);
switch (TYPE_STRUCT(type)->stype) {
case STRUCT_TYPE_4:
AppendGListName(&name_mangle_list, "XUc");
return;
case STRUCT_TYPE_5:
AppendGListName(&name_mangle_list, "Xc");
return;
case STRUCT_TYPE_6:
AppendGListName(&name_mangle_list, "XC");
return;
case STRUCT_TYPE_7:
AppendGListName(&name_mangle_list, "XUs");
return;
case STRUCT_TYPE_8:
AppendGListName(&name_mangle_list, "Xs");
return;
case STRUCT_TYPE_9:
AppendGListName(&name_mangle_list, "XS");
return;
case STRUCT_TYPE_A:
AppendGListName(&name_mangle_list, "XUi");
return;
case STRUCT_TYPE_B:
AppendGListName(&name_mangle_list, "Xi");
return;
case STRUCT_TYPE_C:
AppendGListName(&name_mangle_list, "XI");
return;
case STRUCT_TYPE_D:
AppendGListName(&name_mangle_list, "Xf");
return;
case STRUCT_TYPE_E:
AppendGListName(&name_mangle_list, "Xp");
return;
}
if (TYPE_STRUCT(type)->name && !IsTempName(TYPE_STRUCT(type)->name)) {
CMangler_MangleTypeName(TYPE_STRUCT(type)->name->name);
return;
}
switch (TYPE_STRUCT(type)->stype) {
case STRUCT_TYPE_STRUCT:
AppendGListName(&name_mangle_list, "struct");
break;
case STRUCT_TYPE_UNION:
AppendGListName(&name_mangle_list, "union");
break;
case STRUCT_TYPE_CLASS:
AppendGListName(&name_mangle_list, "class");
break;
default:
#line 701
CError_FATAL();
}
break;
case TYPECLASS:
CMangler_MangleQualifier(qual);
CMangler_MangleClassName(TYPE_CLASS(type));
break;
case TYPETEMPLATE:
AppendGListName(&name_mangle_list, "1T");
break;
default:
#line 716
CError_FATAL();
}
}
void CMangler_MangleType(Type *type, UInt32 qual) {
name_mangle_list.size = 0;
CMangler_MangleTypeAppend(type, qual);
}
static void CMangler_MangleArgs(FuncArg *args) {
TypePointer ptr;
if (args) {
if (args->type) {
while (args) {
if (args != &elipsis && args != &oldstyle) {
if (args->type->type == TYPEPOINTER) {
ptr = *TYPE_POINTER(args->type);
ptr.qual &= ~(Q_CONST | Q_VOLATILE);
CMangler_MangleTypeAppend((Type *) &ptr, args->qual);
} else {
CMangler_MangleTypeAppend(args->type, 0);
}
} else {
AppendGListByte(&name_mangle_list, 'e');
}
args = args->next;
}
} else {
AppendGListByte(&name_mangle_list, 'e');
}
} else {
AppendGListByte(&name_mangle_list, 'v');
}
}
static void CMangler_MangleFunction(Object *obj, NameSpace *nspace) {
TypeFunc *tfunc = TYPE_FUNC(obj->type);
FuncArg *arg = tfunc->args;
AppendGListName(&name_mangle_list, obj->name->name);
if (obj->u.func.inst) {
if (tfunc->flags & FUNC_FLAGS_40)
CMangler_MangleTypeAppend(tfunc->functype, tfunc->qual);
CMangler_AppendTemplateArgumentList(obj->u.func.inst->args);
}
AppendGListName(&name_mangle_list, "__");
while (nspace && nspace->name == NULL)
nspace = nspace->parent;
if (nspace) {
CMangler_MangleNameSpaceName(nspace->parent, nspace->name->name);
if (nspace->theclass) {
if (obj->name == destructor_name_node) {
AppendGListName(&name_mangle_list, "Fv");
return;
}
if (arg) {
if (obj->name == constructor_name_node) {
arg = arg->next;
if (arg && (nspace->theclass->flags & CLASS_FLAGS_20))
arg = arg->next;
} else {
if ((tfunc->flags & FUNC_FLAGS_METHOD) && !TYPE_METHOD(tfunc)->x26) {
CMangler_MangleQualifier(arg->qual);
arg = arg->next;
}
}
}
}
}
AppendGListByte(&name_mangle_list, 'F');
CMangler_MangleArgs(arg);
if (obj->u.func.inst && copts.new_mangler) {
AppendGListByte(&name_mangle_list, '_');
CMangler_MangleTypeAppend(tfunc->functype, tfunc->qual);
}
}
HashNameNode *CMangler_ConversionFuncName(Type *type, UInt32 qual) {
HashNameNode *name;
if (CTemplTool_IsTemplateArgumentDependentType(type))
return GetHashNameNodeExport("__op");
name_mangle_list.size = 0;
AppendGListName(&name_mangle_list, "__op");
CMangler_MangleTypeAppend(type, qual);
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
static HashNameNode *CMangler_MangleNameToUpper(char *str) {
HashNameNode *name;
name_mangle_list.size = 0;
while (*str) {
AppendGListByte(&name_mangle_list, toupper(*(str++)));
}
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
static HashNameNode *CMangler_FunctionLinkName(Object *obj) {
HashNameNode *name;
NameSpace *nspace;
if (obj->u.func.inst)
CMangler_CheckTemplateArguments(obj->u.func.inst->args);
for (nspace = obj->nspace; nspace; nspace = nspace->parent) {
if (nspace->name)
break;
}
name_mangle_list.size = 0;
if (is_pascal_object(obj) && (!nspace || !nspace->theclass)) {
AppendGListData(&name_mangle_list, "_", 1);
AppendGListID(&name_mangle_list, obj->name->name);
} else if ((obj->qual & Q_80000) && (strcmp("main", obj->name->name) || (obj->nspace != cscope_root))) {
AppendGListData(&name_mangle_list, "_", 1);
CMangler_MangleFunction(obj, nspace);
AppendGListByte(&name_mangle_list, 0);
} else {
AppendGListData(&name_mangle_list, "_", 1);
AppendGListID(&name_mangle_list, obj->name->name);
}
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
HashNameNode *CMangler_GetCovariantFunctionName(Object *obj, Type *type) {
HashNameNode *linkname;
HashNameNode *name;
linkname = CMangler_GetLinkName(obj);
name_mangle_list.size = 0;
AppendGListName(&name_mangle_list, linkname->name);
AppendGListName(&name_mangle_list, "@@");
CMangler_MangleTypeAppend(type, 0);
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
static HashNameNode *CMangler_DataLinkName(Object *obj) {
NameSpace *nspace;
HashNameNode *name;
nspace = obj->nspace;
while (nspace && nspace->name == NULL)
nspace = nspace->parent;
name_mangle_list.size = 0;
AppendGListData(&name_mangle_list, "_", 1);
AppendGListName(&name_mangle_list, obj->name->name);
while (nspace && nspace->name == NULL)
nspace = nspace->parent;
if (nspace && (obj->qual & Q_80000)) {
AppendGListName(&name_mangle_list, "__");
CMangler_MangleNameSpaceName(nspace->parent, nspace->name->name);
}
AppendGListByte(&name_mangle_list, 0);
COS_LockHandle(name_mangle_list.data);
name = GetHashNameNodeExport(*name_mangle_list.data);
COS_UnlockHandle(name_mangle_list.data);
return name;
}
HashNameNode *CMangler_GetLinkName(Object *obj) {
while (obj->datatype == DALIAS)
obj = obj->u.alias.object;
switch (obj->datatype) {
case DFUNC:
case DVFUNC:
if (!obj->u.func.linkname)
obj->u.func.linkname = CMangler_FunctionLinkName(obj);
return obj->u.func.linkname;
case DDATA:
if (!obj->u.data.linkname)
obj->u.data.linkname = CMangler_DataLinkName(obj);
return obj->u.data.linkname;
case DINLINEFUNC:
return CMangler_FunctionLinkName(obj);
case DLOCAL:
case DABSOLUTE:
case DLABEL:
return obj->name;
case DNONLAZYPTR:
if (!obj->u.toc.linkname)
obj->u.toc.linkname = CMangler_DataLinkName(obj);
return obj->u.toc.linkname;
default:
#line 1110
CError_FATAL();
return NULL;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,697 @@
#include "compiler.h"
#include "compiler/CError.h"
#include "compiler/PCode.h"
#include "compiler/PCodeInfo.h"
#include "compiler/PCodeUtilities.h"
#include "compiler/enode.h"
#include "compiler/objects.h"
#include "compiler/tokens.h"
#include "compiler/types.h"
static Macro powcM;
static Macro __powcM;
static Macro ppc_cpu;
static Macro profM;
static Macro hostM;
static Macro bendM;
static Macro _ppc_M;
static Macro longI;
static Macro IEEED;
Macro vecM;
Macro altivecM;
static Macro macM2;
static Macro appleM;
static Macro optM;
static Macro alignM;
static Macro _machM;
static Macro archM;
static Macro dynM;
static Macro ppcM;
Object *gFunction;
static ObjectList *temps;
PCodeLabel *returnlabel;
PCodeLabel *cleanreturnlabel;
Boolean needs_cleanup;
Statement *current_statement;
int has_catch_blocks;
int disable_optimizer;
SInt32 current_linenumber;
Boolean has_altivec_arrays;
short high_reg;
short low_reg;
short high_offset;
short low_offset;
short low_reg2;
short high_reg2;
PCodeLabel *pic_base_pcodelabel;
Object *dyld_stub_binding_helper;
Object *rt_cvt_fp2unsigned;
Object *rt_profile_entry;
Object *rt_profile_exit;
Object *rt_div2i;
Object *rt_div2u;
Object *rt_mod2i;
Object *rt_mod2u;
Object *rt_shr2i;
Object *rt_shr2u;
Object *rt_shl2i;
Object *rt_cvt_ull_dbl;
Object *rt_cvt_sll_dbl;
Object *rt_cvt_ull_flt;
Object *rt_cvt_sll_flt;
Object *rt_cvt_dbl_usll;
static void *saveheaperror;
enum {
GPRLimit = 10,
FPRLimit = 13,
VRLimit = 13
};
VarInfo *CodeGen_GetNewVarInfo(void) {
VarInfo *vi;
vi = lalloc(sizeof(VarInfo));
memclrw(vi, sizeof(VarInfo));
vi->deftoken = *CPrep_CurStreamElement();
vi->varnumber = localcount++;
return vi;
}
Object *maketemporary(Type *type) {
ObjectList *list;
Object *obj;
for (list = temps; list; list = list->next) {
obj = list->object;
if (obj->u.var.uid == 0 && obj->type == type) {
obj->u.var.uid = 1;
return obj;
}
}
obj = lalloc(sizeof(Object));
memclrw(obj, sizeof(Object));
obj->otype = OT_OBJECT;
obj->access = ACCESSPUBLIC;
obj->datatype = DLOCAL;
obj->type = type;
obj->name = CParser_GetUniqueName();
obj->u.var.info = CodeGen_GetNewVarInfo();
obj->u.var.uid = 1;
list = lalloc(sizeof(ObjectList));
memclrw(list, sizeof(ObjectList));
list->next = temps;
list->object = obj;
temps = list;
return obj;
}
static void free_temporaries(void) {
ObjectList *list;
for (list = temps; list; list = list->next)
list->object->u.var.uid = 0;
}
static void allocate_temporaries(void) {
ObjectList *list;
for (list = temps; list; list = list->next)
assign_local_memory(list->object);
}
void process_arguments(ArgumentProcessor func, Boolean flag) {
short gpr = 3;
short fpr = 1;
short vr = 2;
Type *type;
ObjectList *list;
for (list = arguments; list; list = list->next) {
type = list->object->type;
if (IS_TYPE_FLOAT(type)) {
func(list->object, (fpr <= FPRLimit) ? fpr : 0);
fpr++;
if (type->size == 4)
gpr++;
else
gpr += 2;
} else if (IS_TYPE_VECTOR(type)) {
func(list->object, (vr <= VRLimit) ? vr : 0);
vr++;
if (flag) {
if ((vr - 1) == 2)
gpr = 9;
else if ((vr - 1) > 2)
gpr = 11;
}
} else {
func(list->object, (gpr <= GPRLimit) ? gpr : 0);
if (TYPE_FITS_IN_REGISTER(type)) {
if (type->size <= 4)
gpr += 1;
else
gpr += 2;
} else {
gpr += (type->size >> 2);
if (type->size & 3)
gpr++;
}
}
}
last_argument_register[RegClass_GPR] = gpr - 1;
last_argument_register[RegClass_FPR] = fpr - 1;
last_argument_register[RegClass_VR] = vr - 1;
if (flag)
move_varargs_to_memory();
}
static void retain_argument_register(Object *obj, short reg) {
VarInfo *vi = Registers_GetVarInfo(obj);
Type *type = obj->type;
if (reg && !vi->noregister && vi->used) {
if (TYPE_FITS_IN_REGISTER(type)) {
if (type->size <= 4) {
retain_register(obj, RegClass_GPR, reg);
} else if (reg < GPRLimit) {
if (copts.little_endian)
retain_GPR_pair(obj, reg, reg + 1);
else
retain_GPR_pair(obj, reg + 1, reg);
}
} else if (IS_TYPE_FLOAT(type)) {
retain_register(obj, RegClass_FPR, reg);
} else if (IS_TYPE_VECTOR(type)) {
retain_register(obj, RegClass_VR, reg);
}
}
}
static void allocate_local_vregs(void) {
VarInfo *vi;
ObjectList *list;
Object *obj;
if (copts.codegen_pic && uses_globals && assignable_registers[RegClass_GPR]) {
if (assignable_registers[RegClass_GPR]) {
vi = pic_base.u.var.info;
vi->reg = 0;
assign_register_by_type(&pic_base);
pic_base_reg = vi->reg;
#line 497
CError_ASSERT(pic_base_reg);
} else {
#line 500
CError_FATAL();
}
} else {
pic_base_reg = 0;
}
for (list = exceptionlist; list; list = list->next) {
obj = list->object;
vi = Registers_GetVarInfo(obj);
if (vi->used && !vi->noregister) {
if (!OBJ_GET_TARGET_VOLATILE(obj) && !vi->reg)
assign_register_by_type(obj);
}
}
set_last_exception_registers();
for (list = arguments; list; list = list->next) {
obj = list->object;
vi = Registers_GetVarInfo(obj);
if (vi->used && !vi->noregister) {
if (!OBJ_GET_TARGET_VOLATILE(obj) && !vi->reg)
assign_register_by_type(obj);
}
}
for (list = locals; list; list = list->next) {
obj = list->object;
if (!IsTempName(obj->name)) {
vi = Registers_GetVarInfo(obj);
if (vi->used && !vi->noregister) {
if (!OBJ_GET_TARGET_VOLATILE(obj) && !vi->reg)
assign_register_by_type(obj);
}
}
}
open_fe_temp_registers();
for (list = locals; list; list = list->next) {
obj = list->object;
if (IsTempName(obj->name)) {
vi = Registers_GetVarInfo(obj);
if (vi->used && !vi->noregister) {
if (!OBJ_GET_TARGET_VOLATILE(obj) && !vi->reg)
assign_register_by_type(obj);
}
}
}
for (list = toclist; list; list = list->next) {
obj = list->object;
vi = Registers_GetVarInfo(obj);
if (!vi->reg && vi->used && vi->usage > 1)
assign_register_by_type(obj);
}
}
static void allocate_local_GPRs(void) {
ObjectList *list;
Object *obj;
Object *winning_obj;
SInt32 winning_usage;
VarInfo *vi;
Type *type;
if (copts.codegen_pic && uses_globals && assignable_registers[RegClass_GPR]) {
vi = pic_base.u.var.info;
vi->reg = 0;
assign_register_by_type(&pic_base);
pic_base_reg = vi->reg;
#line 605
CError_ASSERT(pic_base_reg);
} else {
pic_base_reg = 0;
}
while (assignable_registers[RegClass_GPR]) {
winning_obj = NULL;
winning_usage = -1;
if (!(disable_optimizer & 2)) {
for (list = arguments; list; list = list->next) {
obj = list->object;
vi = Registers_GetVarInfo(obj);
type = obj->type;
if (vi->flags & VarInfoFlag40)
vi->usage = 100000;
if (!vi->reg && vi->used && !vi->noregister) {
if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
if (TYPE_FITS_IN_REGISTER(type) && (!TYPE_IS_8BYTES(type) || assignable_registers[RegClass_GPR] >= 2)) {
winning_obj = obj;
winning_usage = vi->usage;
}
}
}
}
}
if (!(disable_optimizer & 2)) {
for (list = locals; list; list = list->next) {
obj = list->object;
vi = Registers_GetVarInfo(obj);
type = obj->type;
if (vi->flags & VarInfoFlag40)
vi->usage = 100000;
if (!vi->reg && vi->used && !vi->noregister) {
if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
if (TYPE_FITS_IN_REGISTER(type) && (!TYPE_IS_8BYTES(type) || assignable_registers[RegClass_GPR] >= 2)) {
winning_obj = obj;
winning_usage = vi->usage;
}
}
}
}
}
for (list = toclist; list; list = list->next) {
obj = list->object;
vi = Registers_GetVarInfo(obj);
if (vi->flags & VarInfoFlag40)
vi->usage = 100000;
if (!vi->reg && vi->used) {
if (vi->usage >= winning_usage && vi->usage >= 3) {
winning_obj = obj;
winning_usage = vi->usage;
}
}
}
if (!winning_obj)
break;
assign_register_by_type(winning_obj);
#line 698
CError_ASSERT(Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
}
}
static void allocate_local_FPRs(void) {
ObjectList *list;
Object *obj;
Object *winning_obj;
SInt32 winning_usage;
VarInfo *vi;
Type *type;
while (assignable_registers[RegClass_FPR]) {
winning_obj = NULL;
winning_usage = -1;
if (!(disable_optimizer & 2)) {
for (list = arguments; list; list = list->next) {
obj = list->object;
type = obj->type;
vi = Registers_GetVarInfo(obj);
if (vi->flags & VarInfoFlag40)
vi->usage = 100000;
if (!vi->reg && vi->used && !vi->noregister) {
if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
if (IS_TYPE_FLOAT(type)) {
winning_obj = obj;
winning_usage = vi->usage;
}
}
}
}
}
if (!(disable_optimizer & 2)) {
for (list = locals; list; list = list->next) {
obj = list->object;
vi = Registers_GetVarInfo(obj);
if (vi->flags & VarInfoFlag40)
vi->usage = 100000;
if (!vi->reg && vi->used && !vi->noregister) {
if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
if (IS_TYPE_FLOAT(obj->type)) {
winning_obj = obj;
winning_usage = vi->usage;
}
}
}
}
}
if (!winning_obj)
break;
assign_register_by_type(winning_obj);
#line 782
CError_ASSERT(Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
}
}
static void allocate_local_VRs(void) {
ObjectList *list;
Object *obj;
Object *winning_obj;
SInt32 winning_usage;
VarInfo *vi;
while (assignable_registers[RegClass_VR]) {
winning_obj = NULL;
winning_usage = -1;
if (!(disable_optimizer & 2)) {
for (list = arguments; list; list = list->next) {
obj = list->object;
vi = Registers_GetVarInfo(obj);
if (vi->flags & VarInfoFlag40)
vi->usage = 100000;
if (!vi->reg && vi->used && !vi->noregister) {
if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
if (IS_TYPE_VECTOR(obj->type)) {
winning_obj = obj;
winning_usage = vi->usage;
}
}
}
}
}
if (!(disable_optimizer & 2)) {
for (list = locals; list; list = list->next) {
obj = list->object;
vi = Registers_GetVarInfo(obj);
if (vi->flags & VarInfoFlag40)
vi->usage = 100000;
if (!vi->reg && vi->used && !vi->noregister) {
if (!OBJ_GET_TARGET_VOLATILE(obj) && vi->usage >= winning_usage && vi->usage >= 2) {
if (IS_TYPE_VECTOR(obj->type)) {
winning_obj = obj;
winning_usage = vi->usage;
}
}
}
}
}
if (!winning_obj)
break;
assign_register_by_type(winning_obj);
#line 846
CError_ASSERT(Registers_GetVarInfo(winning_obj)->flags & VarInfoFlag2);
}
}
static void allocate_locals(void) {
has_altivec_arrays = 0;
if (!requires_frame && !optimizing)
process_arguments(retain_argument_register, 0);
if (optimizing) {
allocate_local_vregs();
} else {
allocate_local_GPRs();
allocate_local_FPRs();
allocate_local_VRs();
}
assign_locals_to_memory(locals);
}
void move_assigned_argument(Object *obj, short reg) {
VarInfo *vi;
Type *type;
SInt32 bytesLeft;
SInt32 offset;
vi = Registers_GetVarInfo(obj);
type = obj->type;
#line 901
CError_ASSERT(obj->datatype == DLOCAL);
if (!vi->used)
return;
if (reg) {
if (vi->reg) {
if (TYPE_IS_8BYTES(type)) {
if (copts.little_endian) {
if (vi->reg != reg)
emitpcode(PC_MR, vi->reg, reg);
if (reg < GPRLimit) {
#line 916
CError_FAIL((vi->regHi == reg) || (vi->reg == (reg + 1)));
if (vi->regHi != (reg + 1))
emitpcode(PC_MR, vi->regHi, reg + 1);
} else {
load_store_register(PC_LWZ, vi->regHi, local_base_register(obj), obj, high_offset);
}
} else {
if (vi->regHi != reg)
emitpcode(PC_MR, vi->regHi, reg);
if (reg < GPRLimit) {
#line 931
CError_FAIL((vi->reg == reg) || (vi->regHi == (reg + 1)));
if (vi->reg != (reg + 1))
emitpcode(PC_MR, vi->reg, reg + 1);
} else {
load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, low_offset);
}
}
} else if (vi->reg != reg) {
if (IS_TYPE_FLOAT(type)) {
emitpcode(PC_FMR, vi->reg, reg);
} else if (IS_TYPE_VECTOR(type)) {
emitpcode(PC_VMR, vi->reg, reg);
} else {
emitpcode(PC_MR, vi->reg, reg);
}
}
} else {
if (IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type)) {
load_store_register(PC_STW, reg, local_base_register(obj), obj, 0);
} else if (IS_TYPE_INT(type) || IS_TYPE_ENUM(type)) {
switch (type->size) {
case 1:
load_store_register(PC_STB, reg, local_base_register(obj), obj, 0);
break;
case 2:
load_store_register(PC_STH, reg, local_base_register(obj), obj, 0);
break;
case 4:
load_store_register(PC_STW, reg, local_base_register(obj), obj, 0);
break;
case 8:
load_store_register(PC_STW, reg, local_base_register(obj), obj, 0);
if (reg < GPRLimit)
load_store_register(PC_STW, reg + 1, local_base_register(obj), obj, 4);
break;
default:
#line 993
CError_FATAL();
}
} else if (IS_TYPE_FLOAT(type)) {
load_store_register((type->size == 4) ? PC_STFS : PC_STFD, reg, local_base_register(obj), obj, 0);
} else if (IS_TYPE_VECTOR(type)) {
load_store_register(PC_STVX, reg, local_base_register(obj), obj, 0);
} else {
bytesLeft = (11 - reg) * 4;
if (bytesLeft > obj->type->size)
bytesLeft = obj->type->size;
offset = 0;
while (bytesLeft > 0) {
load_store_register(PC_STW, reg, local_base_register(obj), obj, offset);
reg++;
offset += 4;
bytesLeft -= 4;
}
}
}
} else {
if (vi->reg) {
if (IS_TYPE_POINTER(type) || IS_TYPE_4BYTES_MEMBERPOINTER(type)) {
load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, 0);
} else if (IS_TYPE_FLOAT(type)) {
load_store_register((type->size == 4) ? PC_LFS : PC_LFD, vi->reg, local_base_register(obj), obj, 0);
} else if (IS_TYPE_VECTOR(type)) {
load_store_register(PC_LVX, vi->reg, local_base_register(obj), obj, 0);
} else {
switch (type->size) {
case 1:
load_store_register(PC_LBZ, vi->reg, local_base_register(obj), obj, 0);
break;
case 2:
load_store_register(is_unsigned(type) ? PC_LHZ : PC_LHA, vi->reg, local_base_register(obj), obj, 0);
break;
case 4:
load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, 0);
break;
case 8:
load_store_register(PC_LWZ, vi->regHi, local_base_register(obj), obj, high_offset);
load_store_register(PC_LWZ, vi->reg, local_base_register(obj), obj, low_offset);
break;
default:
#line 1095
CError_FATAL();
}
}
} else if (!optimizing) {
local_base_register(obj);
}
}
}
static void load_TOC_pointers(void) {
VarInfo *vi;
Object *obj;
ObjectList *list;
PCode *pc;
if (uses_globals && pic_base_reg) {
pic_base_pcodelabel = makepclabel();
pc = makepcode(PC_BC, 20, 7, 3);
pcsetlinkbit(pc);
pcsetsideeffects(pc);
appendpcode(pclastblock, pc);
pcbranch(pclastblock, pic_base_pcodelabel);
makepcblock();
pclabel(pclastblock, pic_base_pcodelabel);
emitpcode(PC_MFLR, pic_base_reg);
}
// TODO: depends on Operands
for (list = toclist; list; list = list->next) {
}
}
static Boolean has_vararglist(Object *funcobj) {
FuncArg *arg;
arg = TYPE_FUNC(funcobj->type)->args;
while (arg && arg != &elipsis)
arg = arg->next;
return arg == &elipsis;
}
void assign_labels() {
// TODO
}
static Boolean islaststatement(Statement *stmt) {
for (stmt = stmt->next; stmt; stmt = stmt->next) {
if (stmt->type > ST_LABEL)
return 0;
}
return 1;
}
static void newstatement(SInt32 sourceoffset, UInt16 value, int flag) {
PCodeBlock *block = pclastblock;
pcloopweight = value;
if (!block->pcodeCount)
block->loopWeight = value;
if (block->pcodeCount > 100)
branch_label(makepclabel());
if (flag)
block->flags |= fPCBlockFlag4000;
}
static void expressionstatement(ENode *expr) {
}
static void labelstatement() {}
static void gotostatement() {}
static void gotoexpression() {}
static void conditionalstatement() {}
static void returnstatement() {}
static void capturestackpointer() {}
static void resetstackpointer() {}
static void callprofiler() {}
static void exitprofiler() {}
void CodeGen_Generator() {}
void CodeGen_GenVDispatchThunk() {}
void CodeGen_SetupRuntimeObjects() {}
Boolean CodeGen_ReInitRuntimeObjects(Boolean is_precompiler) {}
Boolean CodeGen_IsPublicRuntimeObject(Object *obj) {}
void CodeGen_SOMStub() {}
void CodeGen_ParseDeclSpec() {}
static void CodeGen_EOLCheck() {}
static void schedule_for() {}
static void pragma_scheduling() {}
static void CodeGen_ParseLongIntegerORonORoff() {}
void CodeGen_ParsePragma(HashNameNode *name) {}
void CodeGen_UpdateObject(Object *object) {}
void CodeGen_UpdateBackEndOptions() {}
void CodeGen_objc_method_self_offset() {}
void CodeGen_objc_method_sel_offset() {}
void CodeGen_objc_method_arg_offset() {}
void CodeGen_objc_method_args_size() {}
void CodeGen_HandleIntrinsicCall() {}
void CodeGen_HandleTypeCast() {}
void CodeGen_AssignCheck() {}
void CodeGen_CollapseVectorExpression() {}
void CodeGen_InsertSpecialMacros() {}
char *CodeGen_ExpandSpecialMacro(Macro *macro) {}
void CodeGen_reportheapinfo() {}
static void CodeGen_heaperror() {}
void CodeGen_InitialSanityCheck() {}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,299 @@
#include "compiler.h"
#include "compiler/CompilerTools.h"
#include "compiler/PCode.h"
#include "compiler/PCodeInfo.h"
PCodeBlock *pcbasicblocks;
PCodeBlock *pclastblock;
void *prologue;
void *epilogue;
PCodeBlock **depthfirstordering;
int pcblockcount;
int pcloopweight;
static unsigned short pclabelcount;
void initpcode() {
pclastblock = 0;
pcbasicblocks = 0;
pcblockcount = 0;
pclabelcount = 0;
pcloopweight = 1;
initialize_aliases();
}
PCode *makepcode(short op, ...) {
PCode *pcode;
va_list list;
va_start(list, op);
pcode = vformatpcode(op, list);
pcode->sourceoffset = current_statement ? current_statement->sourceoffset : -1;
return pcode;
}
void emitpcode(short op, ...) {
PCode *pcode;
va_list list;
va_start(list, op);
pcode = vformatpcode(op, list);
pcode->sourceoffset = current_statement ? current_statement->sourceoffset : -1;
appendpcode(pclastblock, pcode);
}
PCode *copypcode(PCode *pcode) {
PCode *newpc;
int extra_arg;
int i;
extra_arg = 0;
if ((PCODE_FLAG_SET_F(pcode) & fPCodeFlag8000000) && !(PCODE_FLAG_SET_F(pcode) & fPCodeFlag20000000))
extra_arg = 1;
newpc = lalloc(sizeof(PCode) + sizeof(PCodeArg) * (pcode->argCount + extra_arg));
memclrw(newpc, sizeof(PCode) + sizeof(PCodeArg) * (pcode->argCount + extra_arg));
newpc->op = pcode->op;
newpc->flags = pcode->flags;
newpc->argCount = pcode->argCount;
newpc->_18 = pcode->_18;
for (i = 0; i < pcode->argCount; i++) {
newpc->args[i] = pcode->args[i];
}
if (extra_arg)
newpc->args[pcode->argCount].kind = PCOp_PLACEHOLDEROPERAND;
return newpc;
}
PCodeLabel *makepclabel() {
PCodeLabel *label;
label = (PCodeLabel *) lalloc(sizeof(PCodeLabel));
memclrw(label, sizeof(PCodeLabel));
label->index = pclabelcount++;
return label;
}
PCodeBlock *makepcblock() {
PCodeBlock *block;
block = (PCodeBlock *) lalloc(sizeof(PCodeBlock));
memclrw(block, sizeof(PCodeBlock));
block->loopWeight = pcloopweight;
block->blockIndex = pcblockcount++;
if (pclastblock) {
pclastblock->nextBlock = block;
block->prevBlock = pclastblock;
} else {
pcbasicblocks = block;
}
pclastblock = block;
return block;
}
void pclabel(PCodeBlock *block, PCodeLabel *label) {
PCLink *iter;
PCLink *next;
iter = (PCLink *) label->block;
while (iter) {
next = (PCLink *) iter->block;
iter->block = block;
iter = next;
}
label->block = block;
label->resolved = 1;
label->nextLabel = block->labels;
block->labels = label;
}
void pcbranch(PCodeBlock *block, PCodeLabel *label) {
PCLink *link;
link = (PCLink *) lalloc(sizeof(PCLink));
memclrw(link, sizeof(PCLink));
link->block = label->block;
if (!label->resolved)
label->block = (PCodeBlock *) link;
link->nextLink = block->successors;
block->successors = link;
}
void pccomputepredecessors() {
PCodeBlock *block;
PCLink *succ;
PCLink *pred;
for (block = pcbasicblocks; block; block = block->nextBlock) {
for (succ = block->successors; succ; succ = succ->nextLink) {
pred = (PCLink *) lalloc(sizeof(PCLink));
memclrw(pred, sizeof(PCLink));
pred->block = block;
pred->nextLink = succ->block->predecessors;
succ->block->predecessors = pred;
}
}
}
void deleteblock(PCodeBlock *block) {
block->prevBlock->nextBlock = block->nextBlock;
if (block->nextBlock)
block->nextBlock->prevBlock = block->prevBlock;
block->flags |= fPCBlockFlag20;
}
void deleteunreachableblocks() {
PCodeBlock *block;
computedepthfirstordering();
for (block = pcbasicblocks->nextBlock; block; block = block->nextBlock) {
if (!(block->flags & fPCBlockFlag4))
deleteblock(block);
}
}
void appendpcode(PCodeBlock *block, PCode *pcode) {
if (block->firstPCode) {
pcode->nextPCode = 0;
pcode->prevPCode = block->lastPCode;
block->lastPCode->nextPCode = pcode;
block->lastPCode = pcode;
} else {
block->lastPCode = pcode;
block->firstPCode = pcode;
pcode->prevPCode = 0;
pcode->nextPCode = 0;
}
pcode->block = block;
block->pcodeCount++;
}
void deletepcode(PCode *pcode) {
PCodeBlock *block;
block = pcode->block;
if (pcode->prevPCode)
pcode->prevPCode->nextPCode = pcode->nextPCode;
else
block->firstPCode = pcode->nextPCode;
if (pcode->nextPCode)
pcode->nextPCode->prevPCode = pcode->prevPCode;
else
block->lastPCode = pcode->prevPCode;
pcode->block = 0;
block->pcodeCount--;
block->flags &= ~fPCBlockFlag8;
}
void insertpcodebefore(PCode *anchor, PCode *newpcode) {
PCodeBlock *block;
block = anchor->block;
if (anchor->prevPCode)
anchor->prevPCode->nextPCode = newpcode;
else
block->firstPCode = newpcode;
newpcode->nextPCode = anchor;
newpcode->prevPCode = anchor->prevPCode;
anchor->prevPCode = newpcode;
newpcode->sourceoffset = anchor->sourceoffset;
newpcode->block = block;
block->pcodeCount++;
block->flags &= ~fPCBlockFlag8;
}
void insertpcodeafter(PCode *anchor, PCode *newpcode) {
PCodeBlock *block;
block = anchor->block;
if (anchor->nextPCode)
anchor->nextPCode->prevPCode = newpcode;
else
block->lastPCode = newpcode;
newpcode->prevPCode = anchor;
newpcode->nextPCode = anchor->nextPCode;
anchor->nextPCode = newpcode;
newpcode->sourceoffset = anchor->sourceoffset;
newpcode->block = block;
block->pcodeCount++;
block->flags &= ~fPCBlockFlag8;
}
void setpcodeflags(int flags) {
pclastblock->lastPCode->flags |= flags;
if (flags & fSideEffects)
pclastblock->lastPCode->flags &= ~(fIsCSE | fCommutative | fPCodeFlag10);
}
void clearpcodeflags(int flags) {
pclastblock->lastPCode->flags &= ~flags;
}
int pccomputeoffsets() {
int offset;
PCodeBlock *block;
offset = 0;
for (block = pcbasicblocks; block; block = block->nextBlock) {
block->codeOffset = offset;
offset += block->pcodeCount * 4;
}
return offset;
}
typedef struct _DFO {
PCodeBlock *block;
PCLink *link;
} DFO;
static int depthfirstorder;
void computedepthfirstordering() {
PCodeBlock *block;
PCLink *link;
DFO *dfo;
int index;
depthfirstordering = (PCodeBlock **) lalloc(sizeof(PCodeBlock *) * pcblockcount);
memclrw(depthfirstordering, sizeof(PCodeBlock *) * pcblockcount);
depthfirstorder = pcblockcount;
for (block = pcbasicblocks; block; block = block->nextBlock) {
block->flags &= ~fPCBlockFlag4;
}
dfo = (DFO *) oalloc(sizeof(DFO) * pcblockcount);
pcbasicblocks->flags |= fPCBlockFlag4;
dfo->block = pcbasicblocks;
dfo->link = pcbasicblocks->successors;
index = 1;
while (index) {
if ((link = dfo[index - 1].link)) {
dfo[index - 1].link = link->nextLink;
block = link->block;
if (!(block->flags & fPCBlockFlag4)) {
block->flags |= fPCBlockFlag4;
dfo[index].block = block;
dfo[index].link = block->successors;
index++;
}
} else {
depthfirstordering[--depthfirstorder] = dfo[--index].block;
}
}
while (depthfirstorder) {
depthfirstordering[--depthfirstorder] = 0;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,348 @@
#include "compiler/PCodeUtilities.h"
#include "compiler/PCode.h"
#include "compiler/PCodeInfo.h"
#include "compiler/CError.h"
#include "compiler/enode.h"
#include "compiler/objects.h"
#include "compiler.h"
void pcsetrecordbit(PCode *pc) {
int reg;
PCodeArg *arg;
short argCount;
int argIdx;
pc->flags &= ~(fPCodeFlag10 | fCommutative | fIsCSE);
if ((pc->flags & (fPCodeFlag80000000 | fPCodeFlag40000000)) == fPCodeFlag40000000) {
reg = 1;
} else if ((pc->flags & (fPCodeFlag80000000 | fPCodeFlag40000000)) == (fPCodeFlag80000000 | fPCodeFlag40000000)) {
reg = 6;
} else {
reg = 0;
}
if (pc->op == PC_ANDI || pc->op == PC_ANDIS) {
pc->flags |= fPCodeFlag20000000;
} else if (pc->op == PC_ADDI || pc->op == PC_ADDIC) {
pc->flags |= fPCodeFlag10000000;
pc->flags |= fPCodeFlag20000000;
change_num_operands(pc, 5);
pc->op = PC_ADDICR;
#line 76
CError_ASSERT(pc->args[3].kind == PCOp_PLACEHOLDEROPERAND);
pc->args[3].kind = PCOp_REGISTER;
pc->args[3].arg = RegClass_SPR;
pc->args[3].data.reg.reg = 0;
pc->args[3].data.reg.effect = EffectWrite;
#line 80
CError_ASSERT(pc->args[4].kind == PCOp_PLACEHOLDEROPERAND);
pc->args[4].kind = PCOp_REGISTER;
pc->args[4].arg = RegClass_CRFIELD;
pc->args[4].data.reg.reg = reg;
pc->args[4].data.reg.effect = EffectWrite;
} else {
arg = pc->args;
argIdx = argCount = pc->argCount;
while (arg->kind != PCOp_PLACEHOLDEROPERAND && argIdx) {
if (arg->kind == PCOp_REGISTER && arg->arg == RegClass_CRFIELD && arg->data.reg.reg == reg) {
arg->data.reg.effect |= EffectWrite;
pc->flags |= fPCodeFlag20000000;
return;
}
arg++;
argIdx--;
}
if (argIdx <= 0) {
arg = &pc->args[argCount];
pc->argCount++;
}
#line 105
CError_ASSERT(arg->kind == PCOp_PLACEHOLDEROPERAND);
arg->kind = PCOp_REGISTER;
arg->arg = RegClass_CRFIELD;
arg->data.reg.reg = reg;
arg->data.reg.effect = EffectWrite;
if (pc->op != PC_ADDICR)
pc->flags |= fPCodeFlag20000000;
}
}
void pcsetsideeffects(PCode *pc) {
pc->flags &= ~(fPCodeFlag10 | fCommutative | fIsCSE);
pc->flags |= fSideEffects;
}
void pcsetlinkbit(PCode *pc) {
PCodeArg *arg;
int argIdx;
switch (pc->op) {
case PC_B:
pc->op = PC_BL;
break;
case PC_BCTR:
pc->op = PC_BCTRL;
break;
case PC_BLR:
pc->op = PC_BLRL;
break;
}
arg = pc->args;
argIdx = pc->argCount;
while (arg->kind != PCOp_PLACEHOLDEROPERAND && argIdx) {
if (arg->kind == PCOp_REGISTER && arg->arg == RegClass_SPR && arg->data.reg.reg == 1) {
arg->data.reg.effect |= EffectWrite;
pc->flags |= fLink;
return;
}
arg++;
argIdx--;
}
#line 169
CError_ASSERT(arg->kind == PCOp_PLACEHOLDEROPERAND);
arg->kind = PCOp_REGISTER;
arg->arg = RegClass_SPR;
arg->data.reg.reg = 1;
arg->data.reg.effect = EffectWrite;
if (opcodeinfo[pc->op].flags & fPCodeFlag8) {
pc->flags &= ~fPCodeFlag1;
pc->flags |= fPCodeFlag8;
}
pc->flags |= fLink;
}
void branch_label(PCodeLabel *label) {
if (pclastblock->pcodeCount) {
pcbranch(pclastblock, label);
makepcblock();
}
pclabel(pclastblock, label);
}
void branch_conditional(short a, short compareop, short c, PCodeLabel *label) {
PCodeBlock *tmpblock;
PCodeLabel *tmplabel;
int r28;
tmpblock = pclastblock;
tmplabel = makepclabel();
switch (compareop) {
case ENOTEQU:
c = !c;
case EEQU:
r28 = 2;
break;
case EGREATEREQU:
c = !c;
case ELESS:
r28 = 0;
break;
case ELESSEQU:
c = !c;
case EGREATER:
r28 = 1;
break;
}
emitpcode(c ? PC_BT : PC_BF, a, r28, label);
pcbranch(pclastblock, label);
pcbranch(pclastblock, tmplabel);
makepcblock();
pclabel(pclastblock, tmplabel);
}
void branch_always(PCodeLabel *label) {
emitpcode(PC_B, label);
pcbranch(pclastblock, label);
makepcblock();
}
void branch_decrement_always(short opcode, PCodeLabel *label) {
PCodeLabel *tmplabel = makepclabel();
emitpcode(opcode, label);
pcbranch(pclastblock, label);
pcbranch(pclastblock, tmplabel);
makepcblock();
pclabel(pclastblock, tmplabel);
}
void branch_indirect(Object *obj) {
emitpcode(PC_BCTR, obj, 0);
makepcblock();
}
int branch_count_volatiles(void) {
int count = 0;
int i;
char rclass;
for (rclass = 0; rclass < RegClassMax; rclass++) {
for (i = 0; i < n_scratch_registers[(char)rclass]; i++) {
count++;
}
}
return count;
}
PCodeArg *branch_record_volatiles(PCodeArg *arglist, UInt32 *masks) {
int i;
char rclass;
for (rclass = RegClassMax - 1; rclass >= 0; rclass--) {
for (i = 0; i < n_scratch_registers[(char)rclass]; i++) {
arglist->kind = PCOp_REGISTER;
arglist->arg = rclass;
arglist->data.reg.reg = scratch_registers[(char)rclass][i];
arglist->data.reg.effect = EffectWrite;
if (masks[(char)rclass] & (1 << scratch_registers[(char)rclass][i]))
arglist->data.reg.effect |= EffectRead;
arglist++;
}
}
return arglist;
}
void branch_subroutine(Object *obj, short add_nop, UInt32 *masks) {
int count;
PCode *pc;
PCodeArg *arg;
count = branch_count_volatiles();
if (copts.exceptions && current_statement)
count += countexceptionactionregisters(current_statement->dobjstack);
pc = makepcode(PC_BL, count, obj, 0);
arg = branch_record_volatiles(pc->args + 1, masks);
if (copts.exceptions && current_statement)
noteexceptionactionregisters(current_statement->dobjstack, arg);
appendpcode(pclastblock, pc);
if (add_nop)
emitpcode(PC_NOP);
branch_label(makepclabel());
if (copts.exceptions && current_statement)
recordexceptionactions(pc, current_statement->dobjstack);
}
void branch_subroutine_ctr(UInt32 *masks) {
int count;
PCode *pc;
PCodeArg *arg;
count = branch_count_volatiles();
if (copts.exceptions && current_statement)
count += countexceptionactionregisters(current_statement->dobjstack);
pc = makepcode(PC_BCTRL, count);
arg = branch_record_volatiles(pc->args + 1, masks);
if (copts.exceptions && current_statement)
noteexceptionactionregisters(current_statement->dobjstack, arg);
appendpcode(pclastblock, pc);
branch_label(makepclabel());
if (copts.exceptions && current_statement)
recordexceptionactions(pc, current_statement->dobjstack);
}
void add_immediate(short dest_reg, short base_reg, Object *obj, short offset) {
short tmp_reg = base_reg;
if (obj && offset && obj->datatype != DLOCAL) {
tmp_reg = used_virtual_registers[RegClass_GPR]++;
add_immediate_lo(tmp_reg, base_reg, obj, 0, 1);
obj = NULL;
}
if (!obj && !offset)
emitpcode(PC_MR, dest_reg, tmp_reg);
else
emitpcode(PC_ADDI, dest_reg, tmp_reg, obj, offset);
}
PCode *add_immediate_lo(short dest_reg, short base_reg, Object *obj, short offset, char add_to_block) {
PCode *pc;
#line 577
CError_ASSERT(obj);
pc = makepcode(PC_ADDI, dest_reg, base_reg, obj, offset);
if (add_to_block)
appendpcode(pclastblock, pc);
return pc;
}
PCode *op_absolute_ha(short dest_reg, short base_reg, Object *obj, short offset, char add_to_block) {
PCode *pc;
int tmp_reg;
if (obj->datatype == DLOCAL) {
pc = makepcode(PC_ADDIS, dest_reg, base_reg, obj, offset);
} else if (copts.codegen_pic) {
tmp_reg = base_reg;
#line 601
CError_ASSERT(tmp_reg);
pc = makepcode(PC_ADDIS, dest_reg, tmp_reg, obj, offset);
} else {
#line 606
CError_ASSERT(base_reg == 0);
pc = makepcode(PC_LIS, dest_reg, obj, offset);
}
if (add_to_block)
appendpcode(pclastblock, pc);
return pc;
}
void load_store_register(short opcode, short dest_reg, short base_reg, Object *obj, SInt32 offset) {
short addi_tmp;
short offset_reg1;
short offset_reg2;
offset_reg1 = base_reg;
if (obj && offset && obj->datatype != DLOCAL) {
offset_reg1 = used_virtual_registers[RegClass_GPR]++;
add_immediate_lo(offset_reg1, base_reg, obj, 0, 1);
obj = NULL;
}
if (offset != (short)offset) {
if (opcode == PC_LWZ && dest_reg == 12)
offset_reg2 = 12;
else if (opcode == PC_LWZ && dest_reg == 11)
offset_reg2 = 11;
else
offset_reg2 = used_virtual_registers[RegClass_GPR]++;
emitpcode(PC_ADDIS, offset_reg2, offset_reg1, 0, (short) ((offset >> 16) + ((offset & 0x8000) >> 15)));
offset = (short) offset;
offset_reg1 = offset_reg2;
}
if (opcode == PC_STVX || opcode == PC_LVX) {
offset_reg2 = 0;
if (obj) {
addi_tmp = used_virtual_registers[RegClass_GPR]++;
emitpcode(PC_ADDI, addi_tmp, offset_reg1, obj, offset);
offset_reg1 = addi_tmp;
} else if (offset) {
offset_reg2 = used_virtual_registers[RegClass_GPR]++;
emitpcode(PC_LI, offset_reg2, offset);
}
if (!offset_reg2)
emitpcode(opcode, dest_reg, 0, offset_reg1);
else
emitpcode(opcode, dest_reg, offset_reg1, offset_reg2);
} else {
emitpcode(opcode, dest_reg, offset_reg1, obj, offset);
}
}

View File

@@ -0,0 +1,392 @@
#include "compiler.h"
#include "compiler/CError.h"
#include "compiler/objects.h"
#include "compiler/PCode.h"
short last_exception_register[RegClassMax];
short first_fe_temporary_register[RegClassMax];
short last_argument_register[RegClassMax];
short _FP_;
short _CALLER_SP_;
char *special_register_names[RegClassMax][RegisterMax];
static short used_regs_before_coloring;
static UInt8 save_state[RegisterMax];
char *XXspecial_register_names[RegClassMax * RegisterMax];
short spr_to_sysreg[4] = {1, 8, 9, 0x100};
void asm_used_register(char rclass, short reg) {
int i;
if ((reg < n_real_registers[rclass]) && (reg_state[rclass][reg] == RegState0)) {
if (reg == nonvolatile_registers[rclass][used_nonvolatile_registers[rclass]]) {
if (assignable_registers[rclass] > 0)
assignable_registers[rclass]--;
reg_state[rclass][reg] = RegState1;
used_nonvolatile_registers[rclass]++;
} else {
for (i = used_nonvolatile_registers[rclass]; i < n_nonvolatile_registers[rclass]; i++) {
if (reg == nonvolatile_registers[rclass][i]) {
reg_state[rclass][reg] = RegState1;
if (assignable_registers[rclass] > 0)
assignable_registers[rclass]--;
}
}
}
}
}
void retain_register(Object *obj, char rclass, short reg) {
VarInfo *vi;
#line 95
CError_ASSERT((short) reg < RegisterMax);
if (reg_state[rclass][reg] == RegState0) {
assignable_registers[rclass]--;
reg_state[rclass][reg] = RegState1;
if (reg == nonvolatile_registers[rclass][used_nonvolatile_registers[rclass]])
used_nonvolatile_registers[rclass]++;
}
if (obj) {
vi = Registers_GetVarInfo(obj);
vi->rclass = rclass;
vi->flags |= VarInfoFlag2;
vi->reg = reg;
}
}
void retain_GPR_pair(Object *obj, short reg, short regHi) {
VarInfo *vi;
retain_register(NULL, RegClass_GPR, reg);
retain_register(NULL, RegClass_GPR, regHi);
if (obj) {
vi = Registers_GetVarInfo(obj);
vi->rclass = RegClass_GPR;
vi->flags |= VarInfoFlag2 | VarInfoFlag4;
vi->reg = reg;
vi->regHi = regHi;
}
}
int is_register_object(Object *obj) {
return obj->sclass == OBJECT_SCLASS_101;
}
int GetABIFirstNonVolatile(char rclass) {
switch (rclass) {
case RegClass_SPR: return 3;
case RegClass_CRFIELD: return 2;
case RegClass_VR: return 20;
case RegClass_GPR: return 13;
case RegClass_FPR: return 14;
default: return -1;
}
}
char GetRegisterClassName(char rclass) {
switch (rclass) {
case RegClass_VR: return 'v';
case RegClass_GPR: return 'r';
case RegClass_FPR: return 'f';
default:
#line 242
CError_FATAL();
return '?';
}
}
static int first_nonvolatile_reg(char rclass) {
return GetABIFirstNonVolatile(rclass);
}
void setup_diagnostic_reg_strings() {
register_class_name[RegClass_SPR] = "SPR";
register_class_format[RegClass_SPR] = "spr%ld";
register_class_name[RegClass_CRFIELD] = "CRFIELD";
register_class_format[RegClass_CRFIELD] = "cr%ld";
register_class_name[RegClass_VR] = "VR";
register_class_format[RegClass_VR] = "vr%ld";
register_class_name[RegClass_FPR] = "FPR";
register_class_format[RegClass_FPR] = "f%ld";
register_class_name[RegClass_GPR] = "GPR";
register_class_format[RegClass_GPR] = "r%ld";
}
void init_target_registers() {
char rclass;
int reg;
int end;
int tmp;
static int last_nonvolatile_reg[] = {3, 5, 31, 31, 31};
static int nonvol_reserve[] = {0, 0, 0, 4, 3};
for (rclass = 0; rclass < RegClassMax; rclass++) {
for (reg = 0; reg < RegisterMax; reg++)
special_register_names[(char)rclass][reg] = NULL;
}
special_register_names[RegClass_SPR][0] = "XER";
special_register_names[RegClass_SPR][1] = "LR";
special_register_names[RegClass_SPR][2] = "CTR";
special_register_names[RegClass_SPR][3] = "VRSAVE";
special_register_names[RegClass_GPR][1] = "SP";
setup_diagnostic_reg_strings();
n_real_registers[RegClass_SPR] = 4;
n_real_registers[RegClass_CRFIELD] = 8;
n_real_registers[RegClass_VR] = 32;
n_real_registers[RegClass_FPR] = 32;
n_real_registers[RegClass_GPR] = 32;
reg_state[RegClass_GPR][1] = RegState2;
reg_state[RegClass_GPR][2] = RegState2;
reg_state[RegClass_CRFIELD][5] = RegState2;
for (rclass = 0; rclass < RegClassMax; rclass++) {
n_nonvolatile_registers[(char)rclass] = 0;
if (last_nonvolatile_reg[(char)rclass] >= 0) {
end = first_nonvolatile_reg(rclass);
for (reg = last_nonvolatile_reg[(char)rclass]; reg >= end; reg--) {
if (reg_state[(char)rclass][reg] == RegState0) {
tmp = n_nonvolatile_registers[(char)rclass]++;
nonvolatile_registers[(char)rclass][tmp] = reg;
}
}
}
assignable_registers[(char)rclass] = n_nonvolatile_registers[(char)rclass] - nonvol_reserve[(char)rclass];
if (assignable_registers[(char)rclass] < 0)
assignable_registers[(char)rclass] = 0;
n_scratch_registers[(char)rclass] = 0;
for (reg = 0; reg < n_real_registers[(char)rclass]; reg++) {
if (reg < GetABIFirstNonVolatile(rclass) || reg > last_nonvolatile_reg[(char)rclass]) {
if (reg_state[(char)rclass][reg] == RegState0) {
tmp = n_scratch_registers[(char)rclass]++;
scratch_registers[(char)rclass][tmp] = reg;
}
}
}
}
_FP_ = -1;
_CALLER_SP_ = -1;
optimizing = (copts.optimizationlevel > 0) && !disable_optimizer;
}
void assign_register_by_type(Object *obj) {
VarInfo *vi;
Type *ty;
Boolean flag;
ty = obj->type;
vi = Registers_GetVarInfo(obj);
flag = 0;
vi->rclass = RegClassMax;
vi->reg = 0;
vi->regHi = 0;
if ((ty->type == TYPEINT) || (ty->type == TYPEENUM) || ((ty->type == TYPEPOINTER || ty->type == TYPEARRAY) && (ty->type != TYPEARRAY)) || ((ty->type == TYPEMEMBERPOINTER) && (ty->size == 4U))) {
if (((ty->type == TYPEINT) || (ty->type == TYPEENUM)) && (ty->size == 8))
flag = 1;
vi->rclass = RegClass_GPR;
} else if (ty->type == TYPEFLOAT) {
vi->rclass = RegClass_FPR;
} else if ((ty->type == TYPESTRUCT) && (TYPE_STRUCT(ty)->stype >= STRUCT_TYPE_4) && (TYPE_STRUCT(ty)->stype <= STRUCT_TYPE_E)) {
vi->rclass = RegClass_VR;
} else {
return;
}
if (vi->rclass < RegClassMax) {
if (flag) {
#line 520
CError_ASSERT(vi->rclass == RegClass_GPR);
if (assignable_registers[vi->rclass] > 1)
assign_GPR_pair(obj);
} else {
if (assignable_registers[vi->rclass] > 0)
assign_register_to_variable(obj, vi->rclass);
}
}
}
void assign_GPR_pair(Object *obj) {
VarInfo *vi;
short reg;
short regHi;
vi = Registers_GetVarInfo(obj);
if (optimizing) {
reg = used_virtual_registers[RegClass_GPR]++;
regHi = used_virtual_registers[RegClass_GPR]++;
} else {
#line 554
CError_ASSERT(assignable_registers[RegClass_GPR] >= 2);
reg = obtain_nonvolatile_register(RegClass_GPR);
regHi = obtain_nonvolatile_register(RegClass_GPR);
retain_GPR_pair(obj, reg, regHi);
}
vi->rclass = RegClass_GPR;
if (reg > 0 && regHi > 0) {
vi->flags |= VarInfoFlag2 | VarInfoFlag4;
vi->reg = reg;
vi->regHi = regHi;
} else {
#line 567
CError_FATAL();
}
}
void open_fe_temp_registers() {
int r;
r = used_virtual_registers[RegClass_GPR];
first_fe_temporary_register[RegClass_GPR] = last_temporary_register[RegClass_GPR] = r;
r = used_virtual_registers[RegClass_FPR];
first_fe_temporary_register[RegClass_FPR] = last_temporary_register[RegClass_FPR] = r;
r = used_virtual_registers[RegClass_VR];
first_fe_temporary_register[RegClass_VR] = last_temporary_register[RegClass_VR] = r;
//first_fe_temporary_register[RegClass_GPR] = last_temporary_register[RegClass_GPR] = used_virtual_registers[RegClass_GPR];
//first_fe_temporary_register[RegClass_FPR] = last_temporary_register[RegClass_FPR] = used_virtual_registers[RegClass_FPR];
//first_fe_temporary_register[RegClass_VR] = last_temporary_register[RegClass_VR] = used_virtual_registers[RegClass_VR];
}
void set_last_exception_registers() {
last_exception_register[RegClass_GPR] = used_virtual_registers[RegClass_GPR] - 1;
last_exception_register[RegClass_FPR] = used_virtual_registers[RegClass_FPR] - 1;
last_exception_register[RegClass_VR] = used_virtual_registers[RegClass_VR] - 1;
}
static VarInfo *Registers_GetNewVarInfo() {
VarInfo *vi = galloc(sizeof(VarInfo));
memclrw(vi, sizeof(VarInfo));
return vi;
}
VarInfo *Registers_GetVarInfo(Object *obj) {
switch (obj->datatype) {
case DDATA:
if (!obj->u.data.info)
obj->u.data.info = Registers_GetNewVarInfo();
return obj->u.data.info;
case DNONLAZYPTR:
// not sure if this is the right union
if (!obj->u.toc.info) {
#line 639
CError_FATAL();
obj->u.toc.info = CodeGen_GetNewVarInfo();
}
return obj->u.toc.info;
case DLOCAL:
if (!obj->u.var.info) {
#line 647
CError_FATAL();
}
return obj->u.var.info;
case DABSOLUTE:
// not sure if this is the right union
if (!obj->u.data.info)
obj->u.data.info = Registers_GetNewVarInfo();
return obj->u.data.info;
default:
#line 660
CError_FATAL();
return NULL;
}
}
int used_vrstate_VRs() {
int count = 0;
int i;
for (i = 0; i < RegisterMax; i++) {
if (reg_state[RegClass_VR][i])
count++;
}
return count;
}
UInt32 colored_vrs_as_vrsave(PCodeBlock *block) {
PCode *pc;
UInt32 mask;
int i;
mask = 0;
if (copts.x1B == 2)
return 0xFFFFFFFF;
if (copts.x1B == 0)
return 0;
while (block) {
for (pc = block->firstPCode; pc; pc = pc->nextPCode) {
if (pc->flags & (fPCodeFlag40000000 | fPCodeFlag80000000)) {
for (i = 0; i < pc->argCount; i++) {
if (pc->args[i].kind == PCOp_REGISTER && pc->args[i].arg == RegClass_VR)
mask |= 1 << (31 - pc->args[i].data.reg.reg);
}
}
}
block = block->nextBlock;
}
return mask;
}
void save_before_coloring_nonvolatile_registers(char rclass) {
used_regs_before_coloring = used_nonvolatile_registers[rclass];
memcpy(save_state, reg_state[rclass], sizeof(save_state));
}
void reset_nonvolatile_registers(char rclass) {
used_nonvolatile_registers[rclass] = used_regs_before_coloring;
memcpy(reg_state[rclass], save_state, sizeof(save_state));
}
int is_nonvolatile_register(char rclass, int reg) {
int i;
for (i = 0; i < n_nonvolatile_registers[rclass]; i++) {
if (reg == nonvolatile_registers[rclass][i])
return 1;
}
return 0;
}
void init_endian() {
if (copts.little_endian) {
high_offset = 4;
low_offset = 0;
high_reg = 4;
low_reg = 3;
high_reg2 = 6;
low_reg2 = 5;
} else {
high_offset = 0;
low_offset = 4;
high_reg = 3;
low_reg = 4;
high_reg2 = 5;
low_reg2 = 6;
}
}
void update_asm_nonvolatile_registers() {
char rclass;
int r31;
for (rclass = 0; rclass < RegClassMax; rclass++) {
for (r31 = n_nonvolatile_registers[rclass] - 1; r31 >= 0; r31--) {
if (reg_state[rclass][nonvolatile_registers[rclass][r31]] == RegState1)
break;
}
if (r31 > used_nonvolatile_registers[rclass])
used_nonvolatile_registers[rclass] = r31;
}
}

View File

@@ -0,0 +1,225 @@
#include "compiler.h"
#include "compiler/objects.h"
#include "compiler/PCode.h"
// haven't checked this object file for .data stuff yet
// ONLY FOR TESTING
// this file gets kinda fucked up by the loop unroller
//#pragma opt_unroll_loops off
int used_virtual_registers[RegClassMax];
int used_nonvolatile_registers[RegClassMax];
int assignable_registers[RegClassMax];
int n_real_registers[RegClassMax];
int n_scratch_registers[RegClassMax];
int scratch_registers[RegClassMax][RegisterMax];
int n_nonvolatile_registers[RegClassMax];
int nonvolatile_registers[RegClassMax][RegisterMax];
UInt8 reg_state[RegClassMax][RegisterMax];
int first_temporary_register[RegClassMax];
int last_temporary_register[RegClassMax];
char *register_class_name[RegClassMax];
char *register_class_format[RegClassMax];
int coloring;
int optimizing;
typedef struct ModifiedRegisters {
struct ModifiedRegisters *next;
Object *obj;
UInt32 mask[RegClassMax];
} ModifiedRegisters;
static ModifiedRegisters *mod_regs_table[128];
void init_registers() {
char rclass;
int j;
for (rclass = 0; rclass < RegClassMax; rclass++) {
for (j = 0; j < RegisterMax; j++) {
reg_state[(char)rclass][j] = RegState0;
}
}
for (rclass = 0; rclass < RegClassMax; rclass++)
used_nonvolatile_registers[(char)rclass] = 0;
optimizing = 1;
init_target_registers();
for (rclass = 0; rclass < RegClassMax; rclass++)
used_virtual_registers[(char)rclass] = n_real_registers[(char)rclass];
coloring = 1;
}
void assign_register_to_variable(Object *obj, char rclass) {
VarInfo *vi;
short reg;
vi = Registers_GetVarInfo(obj);
if (optimizing) {
reg = used_virtual_registers[rclass]++;
} else {
reg = obtain_nonvolatile_register(rclass);
retain_register(obj, rclass, reg);
}
vi->flags |= VarInfoFlag2;
vi->rclass = rclass;
vi->reg = reg;
}
void retain_register_for_argument(Object *obj, char rclass, short reg) {
VarInfo *vi = obj->u.var.info;
reg_state[rclass][reg] = RegState1;
vi->flags |= VarInfoFlag2;
vi->rclass = rclass;
vi->reg = reg;
}
int available_registers(char rclass) {
int i;
int count = 0;
for (i = 0; i < n_real_registers[rclass]; i++) {
if (reg_state[rclass][i] == RegState0)
count++;
}
return count;
}
UInt32 volatile_registers(char rclass) {
UInt32 mask = 0;
int i;
int reg;
for (i = 0; i < n_scratch_registers[rclass]; i++) {
reg = scratch_registers[rclass][i];
if (reg_state[rclass][reg] == RegState0)
mask |= 1 << reg;
}
return mask;
}
short obtain_nonvolatile_register(char rclass) {
int best = -1;
while (used_nonvolatile_registers[rclass] < n_nonvolatile_registers[rclass]) {
int tmp = nonvolatile_registers[rclass][used_nonvolatile_registers[rclass]++];
if (reg_state[rclass][tmp] == RegState0) {
best = tmp;
break;
}
}
return best;
}
void open_temp_registers() {
int rclass;
for (rclass = 0; (char)rclass < RegClassMax; rclass++) {
int r = used_virtual_registers[(char)rclass];
//last_temporary_register[rclass] = r;
//first_temporary_register[rclass] = r;
first_temporary_register[(char)rclass] = last_temporary_register[(char)rclass] = r;
}
/*rclass = 0;
while (rclass < RegClassMax) {
r = used_virtual_registers[(char)rclass];
last_temporary_register[(char)rclass] = r;
first_temporary_register[(char)rclass] = r;
rclass = rclass + 1;
}*/
}
void check_temp_registers() {
char rclass;
if (!optimizing) {
for (rclass = 0; rclass < RegClassMax; rclass++) {
if (used_virtual_registers[(char)rclass] > last_temporary_register[(char)rclass])
last_temporary_register[(char)rclass] = used_virtual_registers[(char)rclass];
if (used_virtual_registers[(char)rclass] > 256)
used_virtual_registers[(char)rclass] = first_temporary_register[(char)rclass];
}
}
}
void close_temp_registers() {
char rclass;
for (rclass = 0; rclass < RegClassMax; rclass++) {
if (used_virtual_registers[(char)rclass] < last_temporary_register[(char)rclass])
used_virtual_registers[(char)rclass] = last_temporary_register[(char)rclass];
else
last_temporary_register[(char)rclass] = used_virtual_registers[(char)rclass];
}
}
int count_scratch_registers() {
int rclass;
int count;
count = 0;
for (rclass = 0; (char)rclass < RegClassMax; rclass++)
count += n_scratch_registers[(char)rclass];
return count;
}
void init_modified_registers() {
int i = 0;
for (i = 0; i < 128; i++)
mod_regs_table[i] = NULL;
}
static void compute_modified_registers(UInt32 *masks) {
int rclass;
PCodeBlock *block;
PCode *pcode;
int i;
for (rclass = 0; rclass < RegClassMax; rclass++)
masks[(char)rclass] = 0;
for (block = pcbasicblocks; block; block = block->nextBlock) {
for (pcode = block->firstPCode; pcode; pcode = pcode->nextPCode) {
for (i = 0; i < pcode->argCount; i++) {
if (pcode->args[i].kind == PCOp_REGISTER && pcode->args[i].data.reg.effect & EffectWrite)
masks[pcode->args[i].arg] |= 1 << pcode->args[i].data.reg.reg;
}
}
}
}
void note_modified_registers(Object *obj) {
ModifiedRegisters *mr;
mr = galloc(sizeof(ModifiedRegisters));
mr->obj = obj;
compute_modified_registers(mr->mask);
mr->next = mod_regs_table[obj->name->hashval];
mod_regs_table[obj->name->hashval] = mr;
}
void find_modified_registers(Object *obj, UInt32 *masks) {
char rclass;
ModifiedRegisters *scan;
for (rclass = 0; rclass < RegClassMax; rclass++)
masks[(char)rclass] = 0xFFFFFFFF;
if (CParser_HasInternalLinkage(obj)) {
for (scan = mod_regs_table[obj->name->hashval]; scan; scan = scan->next) {
if (scan->obj == obj)
break;
}
if (scan) {
for (rclass = 0; rclass < RegClassMax; rclass++)
masks[(char)rclass] = scan->mask[(char)rclass];
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff