diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
commit | 094b96ca1df4a035b5f93c351f773306c0241f3f (patch) | |
tree | 95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/InlineAsmPPC.c | |
parent | fc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff) | |
download | MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip |
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/InlineAsmPPC.c')
-rw-r--r-- | compiler_and_linker/unsorted/InlineAsmPPC.c | 2586 |
1 files changed, 0 insertions, 2586 deletions
diff --git a/compiler_and_linker/unsorted/InlineAsmPPC.c b/compiler_and_linker/unsorted/InlineAsmPPC.c deleted file mode 100644 index 464f9f9..0000000 --- a/compiler_and_linker/unsorted/InlineAsmPPC.c +++ /dev/null @@ -1,2586 +0,0 @@ -#include "compiler/InlineAsmPPC.h" -#include "compiler/CError.h" -#include "compiler/CExpr.h" -#include "compiler/CInt64.h" -#include "compiler/CFunc.h" -#include "compiler/CMachine.h" -#include "compiler/CParser.h" -#include "compiler/CPrep.h" -#include "compiler/CPrepTokenizer.h" -#include "compiler/Alias.h" -#include "compiler/CodeGen.h" -#include "compiler/CodeGenOptPPC.h" -#include "compiler/CompilerTools.h" -#include "compiler/Exceptions.h" -#include "compiler/FuncLevelAsmPPC.h" -#include "compiler/InlineAsm.h" -#include "compiler/InlineAsmMnemonicsPPC.h" -#include "compiler/InlineAsmRegisters.h" -#include "compiler/InlineAsmRegistersPPC.h" -#include "compiler/PCode.h" -#include "compiler/PCodeUtilities.h" -#include "compiler/PPCError.h" -#include "compiler/RegisterInfo.h" -#include "compiler/StackFrame.h" -#include "compiler/TOC.h" -#include "compiler/objects.h" - -char asm_alloc_flags[10]; -Section sm_section; -UInt32 cpu; -SInt32 fralloc_parameter_area_size; -Boolean user_responsible_for_frame; -Boolean supports_hardware_fpu; -UInt32 assembledinstructions; -AssemblerType assembler_type; -char volatileasm; -Boolean InlineAsm_gccmode; -Boolean InlineAsm_labelref; -CLabel *pic_base_label; - -// forward decls -static SInt32 InlineAsm_ConstantExpressionPPC(SInt32 value); -static Object *isvariableoperand(void); -static Object *isregisterstructpointeroperand(void); -static void registeroperand(IAOperand *op, char rclass, short effect); -static void DiadicOperatorPPC(IAExpr *left, short token, IAExpr *right); -static void InlineAsm_ExpressionPPC(IAExpr *expr, SInt32 value); -static void savepicbase(short reg, HashNameNode *name); - -CW_INLINE SInt32 ExtractValue(CInt64 value) { - return (SInt32) CInt64_GetULong(&value); -} - -static void IllegalObjectOperator(HashNameNode *name1, HashNameNode *name2, short token) { - char *opstr; - switch (token) { - case '*': opstr = "*"; break; - case '/': opstr = "/"; break; - case '%': opstr = "%"; break; - case '+': opstr = "+"; break; - case '-': opstr = "-"; break; - case TK_SHL: opstr = "<<"; break; - case TK_SHR: opstr = ">>"; break; - case '<': opstr = "<"; break; - case '>': opstr = ">"; break; - // bug? these two seem swapped - case TK_LESS_EQUAL: opstr = ">="; break; - case TK_GREATER_EQUAL: opstr = "<="; break; - case TK_LOGICAL_EQ: opstr = "=="; break; - case TK_LOGICAL_NE: opstr = "!="; break; - case '&': opstr = "&"; break; - case '^': opstr = "^"; break; - case '|': opstr = "|"; break; - case TK_LOGICAL_AND: opstr = "&&"; break; - case TK_LOGICAL_OR: opstr = "||"; break; - default: opstr = "???"; - } - - if (!name2) { - PPCError_Error(PPCErrorStr119, opstr, name1->name); - } else if (!name1) { - PPCError_Error(PPCErrorStr120, opstr, name2->name); - } else { - PPCError_Error(PPCErrorStr118, name1->name, opstr, name2->name); - } -} - -static void IllegalObjectInConst(IAExpr *expr) { - if (expr->xC) { - PPCError_Error(PPCErrorStr122, expr->xC->name->name); - } else if (expr->object) { - PPCError_Error(PPCErrorStr122, expr->object->name->name); - } else if (expr->label) { - PPCError_Error(PPCErrorStr166, expr->label->name->name); - } -} - -static void NotInRegisterError(char *name, char rclass) { - PPCError_Error(PPCErrorStr167, name, register_class_name[rclass]); -} - -static int isregisteroperand(char rclass) { - IARegister *reg; - - return (tk == TK_IDENTIFIER && (reg = InlineAsm_LookupRegisterPPCName(tkidentifier)) && reg->rclass == rclass); -} - -static SInt32 getcroperand(char rclass) { - SInt32 value; - IARegister *reg; - - value = 0; - if (tk == TK_IDENTIFIER && (reg = InlineAsm_LookupRegisterPPCName(tkidentifier)) && reg->rclass == rclass) { - value = reg->num; - } else { - PPCError_Error(PPCErrorStr167, tkidentifier->name); - } - - tk = lex(); - return value; -} - -static SInt32 getimmediateoperand(SInt32 minimum, SInt32 maximum) { - SInt32 value = InlineAsm_ConstantExpressionPPC(0); - if (value < minimum || value > maximum) - CError_Error(CErrorStr154); - return value; -} - -static void PrimaryExpressionPPC(IAExpr *expr, SInt32 value) { - Object *obj; - IALookupResult result; - IAExpr subexpr; - IAExprType type = IAExpr_0; - SInt32 v; - - switch (tk) { - case TK_IDENTIFIER: - if ((obj = isregisterstructpointeroperand())) { - tk = lex(); - InlineAsm_InitExpr5(expr, InlineAsm_StructPointerMemberOffset(TPTR_TARGET(obj->type))); - expr->object = obj; - return; - } - - if ((obj = isvariableoperand())) { - short reg; - InlineAsm_InitExpr5(expr, 0); - expr->xC = obj; - - if (obj->datatype == DLOCAL) - reg = 1; - else - reg = pic_base_reg; - - tk = lex(); - if (tk == '.' || tk == '[') { - InlineAsm_InitExpr5(&subexpr, InlineAsm_StructArrayMemberOffset(obj->type)); - DiadicOperatorPPC(expr, '+', &subexpr); - } - - if (tk == '+') { - tk = lex(); - InlineAsm_ExpressionPPC(&subexpr, value); - DiadicOperatorPPC(expr, '+', &subexpr); - } else if (tk == '-') { - tk = lex(); - InlineAsm_ExpressionPPC(&subexpr, value); - DiadicOperatorPPC(expr, '-', &subexpr); - } else if (!strcmp(tkidentifier->name, "@loword")) { - tk = lex(); - if (low_offset) { - InlineAsm_InitExpr5(&subexpr, low_offset); - DiadicOperatorPPC(expr, '+', &subexpr); - } - } else if (!strcmp(tkidentifier->name, "@hiword")) { - tk = lex(); - if (high_offset) { - InlineAsm_InitExpr5(&subexpr, high_offset); - DiadicOperatorPPC(expr, '+', &subexpr); - } - } - expr->reg = reg; - return; - } - - if (InlineAsm_LookupSymbolOrTag(tkidentifier, &result, 1)) { - if (result.has_value) { - tk = lex(); - InlineAsm_InitExpr5(expr, result.value); - return; - } - - if (result.type && (IS_TYPE_STRUCT(result.type) || IS_TYPE_CLASS(result.type))) { - tk = lex(); - if (tk != '.') - CError_Error(CErrorStr120); - - if (allow_array_expressions) { - InlineAsm_InitExpr5(expr, InlineAsm_StructArrayMemberOffset(result.type)); - return; - } - - InlineAsm_InitExpr5(expr, InlineAsm_StructMemberOffset(result.type)); - return; - } - - if (result.object && result.object->datatype == DABSOLUTE) { - tk = lex(); - InlineAsm_InitExpr5(expr, result.object->u.address); - return; - } - } else if (value) { - if (isregisteroperand(RegClass_CRFIELD)) { - InlineAsm_InitExpr5(expr, getcroperand(RegClass_CRFIELD)); - return; - } - if (isregisteroperand(RegClass_6)) { - InlineAsm_InitExpr5(expr, getcroperand(RegClass_6)); - return; - } - if (strlen(tkidentifier->name) == 6 && !strncmp(tkidentifier->name, "cr", 2) && tkidentifier->name[3] == '_') { - IARegister *reg; - char regname[4]; - regname[0] = tkidentifier->name[0]; - regname[1] = tkidentifier->name[1]; - regname[2] = tkidentifier->name[2]; - regname[3] = 0; - if ((reg = InlineAsm_LookupRegisterPPC(regname)) && reg->rclass == RegClass_CRFIELD) { - SInt32 v = reg->num * 4; - regname[0] = tkidentifier->name[4]; - regname[1] = tkidentifier->name[5]; - regname[2] = 0; - if ((reg = InlineAsm_LookupRegisterPPC(regname)) && reg->rclass == RegClass_6) { - tk = lex(); - InlineAsm_InitExpr5(expr, v + reg->num); - return; - } - } - } - } - - if (!strcmp("ha16", tkidentifier->name)) - type = IAExpr_8; - else if (!strcmp("hi16", tkidentifier->name)) - type = IAExpr_7; - else if (!strcmp("lo16", tkidentifier->name)) - type = IAExpr_6; - - if (type != IAExpr_0) { - tk = lex(); - if (tk == '(') { - SInt32 v; - tk = lex(); - PrimaryExpressionPPC(expr, value); - expr->type = type; - if (tk != ')') - CError_Error(CErrorStr115); - - tk = lex(); - if (InlineAsm_CheckExpr(expr)) { - expr->value = InlineAsm_GetExprValue(expr); - expr->type = IAExpr_5; - } - return; - } - - CError_Error(CErrorStr114); - } else { - if (!result.label) - result.label = InlineAsm_DeclareLabel(tkidentifier); - - InlineAsm_InitExpr5(expr, 0); - expr->flags |= IAFlag1; - expr->label = result.label; - tk = lex(); - return; - } - break; - - case TK_INTCONST: - v = CInt64_GetULong(&tkintconst); - tk = lex(); - InlineAsm_InitExpr5(expr, v); - return; - - case TK_SIZEOF: - InlineAsm_InitExpr5(expr, scansizeof()); - return; - - case '+': - tk = lex(); - PrimaryExpressionPPC(expr, value); - return; - - case '-': - tk = lex(); - PrimaryExpressionPPC(expr, value); - if (InlineAsm_CheckExpr(expr)) - expr->value = -expr->value; - else - CError_Error(CErrorStr124); - return; - - case '!': - tk = lex(); - PrimaryExpressionPPC(expr, value); - if (InlineAsm_CheckExpr(expr)) - expr->value = !expr->value; - else - CError_Error(CErrorStr124); - return; - - case '~': - tk = lex(); - PrimaryExpressionPPC(expr, value); - if (InlineAsm_CheckExpr(expr)) - expr->value = ~expr->value; - else - CError_Error(CErrorStr124); - return; - - case '(': - tk = lex(); - InlineAsm_ExpressionPPC(expr, value); - if (tk != ')') - CError_Error(CErrorStr115); - tk = lex(); - return; - - default: - CError_Error(CErrorStr120); - } - - InlineAsm_InitExpr5(expr, 0); -} - -static void DiadicOperatorPPC(IAExpr *left, short token, IAExpr *right) { - CInt64 leftval; - CInt64 rightval; - - CInt64_SetLong(&leftval, left->value); - CInt64_SetLong(&rightval, right->value); - rightval = CMach_CalcIntDiadic(TYPE(&stsignedint), leftval, token, rightval); - - if (left->xC) { - if (right->label) - PPCError_Error(PPCErrorStr124, left->xC->name->name, right->label->name->name); - - if (right->xC) { - if (left->x10) { - PPCError_Error(PPCErrorStr121, left->xC->name->name, left->x10->name->name, right->xC->name->name); - } else if (right->x10) { - PPCError_Error(PPCErrorStr121, left->xC->name->name, right->xC->name->name, right->x10->name->name); - } else if (token == '-') { - left->value = CInt64_GetULong(&rightval); - left->x10 = right->xC; - } else { - IllegalObjectOperator(left->xC->name, right->xC->name, token); - } - } else if (token == '-' || token == '+') { - left->value = CInt64_GetULong(&rightval); - } else { - IllegalObjectOperator(left->xC->name, NULL, token); - } - } else if (right->xC) { - if (right->label) - PPCError_Error(PPCErrorStr124, right->xC->name->name, right->label->name->name); - - if (token == '+') { - left->xC = right->xC; - left->x10 = right->x10; - left->value = CInt64_GetULong(&rightval); - } else { - IllegalObjectOperator(NULL, right->xC->name, token); - } - } else if (left->label) { - if (left->xC) - PPCError_Error(PPCErrorStr124, left->label->name->name, left->xC->name->name); - - if (right->label) { - if (left->x18) { - PPCError_Error(PPCErrorStr121, left->label->name->name, left->x18->name->name, right->label->name->name); - } else if (right->x18) { - PPCError_Error(PPCErrorStr121, left->label->name->name, right->label->name->name, right->x18->name->name); - } else if (token == '-') { - left->value = CInt64_GetULong(&rightval); - left->x18 = right->label; - } else { - IllegalObjectOperator(left->label->name, right->label->name, token); - } - } else if (token == '+' || token == '-') { - left->value = CInt64_GetULong(&rightval); - } else { - IllegalObjectOperator(NULL, left->label->name, token); - } - } else if (right->label) { - if (token == '+') { - left->label = right->label; - left->x18 = right->x18; - left->value = CInt64_GetULong(&rightval); - } else { - IllegalObjectOperator(NULL, right->label->name, token); - } - } else { - left->value = CInt64_GetULong(&rightval); - } - - left->flags |= right->flags; - if (left->type == IAOpnd_Lab) { - if (right->type != IAOpnd_Lab) - left->type = right->type; - } else { - if (right->type != IAOpnd_Lab && right->type != left->type) - PPCError_Error(PPCErrorStr126); - } -} - -static void ExpressionTailPPC(IAExpr *left, SInt32 value) { - IAExpr right; - short left_tk; - short right_prec; - - while (1) { - left_tk = tk; - tk = lex(); - - PrimaryExpressionPPC(&right, value); - right_prec = GetPrec(tk); - if (right_prec == 0) { - DiadicOperatorPPC(left, left_tk, &right); - break; - } - - if (GetPrec(left_tk) >= right_prec) { - DiadicOperatorPPC(left, left_tk, &right); - } else { - ExpressionTailPPC(&right, value); - DiadicOperatorPPC(left, left_tk, &right); - if (GetPrec(tk) == 0) - break; - } - } -} - -static void immediateoperand(IAOperand *op, SInt32 minval, SInt32 maxval) { - SInt32 value; - if (InlineAsm_gccmode && tk == '%') { - tk = lex(); - if (tk != TK_INTCONST) { - CError_Error(CErrorStr144); - } else { - CInt64 c = tkintconst; - value = CInt64_GetULong(&c); - if (value < 0) - CError_Error(CErrorStr144); - } - op->type = IAOpnd_7; - op->u.unk7.value = value; - op->u.unk7.unk1 = 1; - op->u.unk7.unk2 = 0; - op->u.unk7.unk3 = 0; - tk = lex(); - } else { - value = InlineAsm_ConstantExpressionPPC(0); - if (value < minval || value > maxval) - CError_Error(CErrorStr154); - op->type = IAOpnd_Imm; - op->u.imm.value = value; - } -} - -static SInt32 immediatevalue(IAOperand *op, SInt32 minval, SInt32 maxval) { - SInt32 value; - if (InlineAsm_gccmode && tk == '%') { - CError_Error(CErrorStr144); - return 0; - } else { - value = InlineAsm_ConstantExpressionPPC(0); - if (value < minval || value > maxval) - CError_Error(CErrorStr154); - op->type = IAOpnd_Imm; - op->u.imm.value = value; - return value; - } -} - -static void InlineAsm_ExpressionPPC(IAExpr *expr, SInt32 value) { - PrimaryExpressionPPC(expr, value); - if (GetPrec(tk)) - ExpressionTailPPC(expr, value); - if (GetPrec(tk)) - ExpressionTailPPC(expr, value); - - if (expr->type == IAExpr_5 && tk == TK_IDENTIFIER) { - if (!strcmp(tkidentifier->name, "@l")) { - expr->type = IAExpr_6; - tk = lex(); - } else if (!strcmp(tkidentifier->name, "@ha")) { - expr->type = IAExpr_8; - tk = lex(); - } else if (!strcmp(tkidentifier->name, "@h")) { - expr->type = IAExpr_7; - tk = lex(); - } - } -} - -static SInt32 InlineAsm_ConstantExpressionPPC(SInt32 value) { - IAExpr expr; - - InlineAsm_ExpressionPPC(&expr, value); - if (!InlineAsm_CheckExpr(&expr)) { - IllegalObjectInConst(&expr); - return 0; - } else { - return InlineAsm_GetExprValue(&expr); - } -} - -static SInt32 crbitoperand(void) { - SInt32 value = InlineAsm_ConstantExpressionPPC(1); - if (value < 0 || value > 31) - CError_Error(CErrorStr154); - return value; -} - -static void floatoperand(IAOperand *op, InlineAsm *ia, Type *type) { - Object *obj; - - obj = createfloatconstant(type, &tkfloatconst); - op[0].type = IAOpnd_Reg; - op[0].u.reg.rclass = RegClass_GPR; - op[0].u.reg.object = NULL; - op[0].u.reg.effect = EffectRead; - op[0].u.reg.num = pic_base_reg; - - ia->argcount++; - op[1].type = IAOpnd_4; - op[1].u.obj.obj = obj; - PPCError_Error(PPCErrorStr179); - op[1].u.obj.unk = IAExpr_2; - op[1].u.obj.offset = 0; - tk = lex(); -} - -static Object *isvariableoperand(void) { - IALookupResult result; - Object *obj; - - if (tk == TK_IDENTIFIER) { - InlineAsm_LookupSymbol(tkidentifier, &result); - if ((obj = result.object)) { - if (obj->datatype == DLOCAL) { - if (OBJECT_REG(obj)) - return NULL; - return obj; - } - - if (obj->datatype == DFUNC || obj->datatype == DVFUNC) - return obj; - - if (obj->datatype == DDATA) { - createIndirect(obj, 0, 0); - return obj; - } - } - } - - return NULL; -} - -static Object *isregisterstructpointeroperand(void) { - IALookupResult result; - Object *obj; - - if (tk != TK_IDENTIFIER) - return NULL; - - InlineAsm_LookupSymbol(tkidentifier, &result); - if ((obj = result.object)) { - if (obj->datatype != DLOCAL) - return NULL; - if (!OBJECT_REG(obj) && !is_register_object(obj)) - return NULL; - if (!IS_TYPE_POINTER(obj->type)) - return NULL; - if (!IS_TYPE_STRUCT(TPTR_TARGET(obj->type)) && !IS_TYPE_CLASS(TPTR_TARGET(obj->type))) - return NULL; - return obj; - } - - return NULL; -} - -static void memoryoperand(IAOperand *op, InlineAsm *ia, Boolean flag, short effect) { - IAExpr expr; - - InlineAsm_ExpressionPPC(&expr, 0); - if (expr.object) { - if (!flag) - CError_Error(CErrorStr155); - if (expr.xC) - PPCError_Error(PPCErrorStr122, expr.xC); - - op[0].type = IAOpnd_Reg; - op[0].u.reg.rclass = RegClass_GPR; - op[0].u.reg.object = expr.object; - op[0].u.reg.num = 0; - op[0].u.reg.effect = effect; - if (expr.object || expr.reg) - op[0].u.reg.effect = effect; - else - op[0].u.reg.effect = 0; - - ia->argcount++; - op[1].type = IAOpnd_Imm; - switch (expr.type) { - case IAExpr_5: - expr.type = IAExpr_6; - if (expr.object->datatype != DLOCAL || !OBJECT_REG(expr.object)) - PPCError_Error(PPCErrorStr180); - case IAExpr_2: - case IAExpr_6: - case IAExpr_7: - case IAExpr_8: - op[1].u.imm.value = InlineAsm_GetExprValue(&expr); - break; - default: - CError_Error(CErrorStr155); - } - - expr.object->flags |= OBJECT_USED; - return; - } - - if (expr.xC) { - if (expr.x10) - PPCError_Error(PPCErrorStr123, expr.xC->name->name, expr.x10->name->name); - - if (flag) { - if (tk == '(') { - if (flag) { - tk = lex(); - registeroperand(op, RegClass_GPR, effect); - if ((expr.type == IAExpr_8 || expr.type == IAExpr_7) && copts.codegen_pic && pic_base_reg) - CError_Error(CErrorStr155); - if (tk != ')') - CError_Error(CErrorStr115); - tk = lex(); - } - } else { - op[0].type = IAOpnd_Reg; - op[0].u.reg.rclass = RegClass_GPR; - op[0].u.reg.object = expr.object; - op[0].u.reg.num = expr.reg; - } - - if (expr.object || expr.reg) - op[0].u.reg.effect = effect; - else - op[0].u.reg.effect = 0; - - ia->argcount++; - op++; - } - - if (expr.xC->datatype == DLOCAL) { - op[0].type = IAOpnd_4; - op[0].u.obj.unk = IAExpr_1; - } else { - op[0].type = IAOpnd_3; - if (expr.type == IAExpr_5) { - expr.type = IAExpr_6; - PPCError_Error(PPCErrorStr180); - } - op[0].u.obj.unk = expr.type; - } - - op[0].u.obj.obj = expr.xC; - op[0].u.obj.offset = expr.value; - expr.xC->flags |= OBJECT_USED; - return; - } - - if (flag) { - if (tk == '(') { - tk = lex(); - registeroperand(op, RegClass_GPR, effect); - ia->argcount++; - op++; - if (tk != ')') - CError_Error(CErrorStr115); - tk = lex(); - } else { - op->type = IAOpnd_Reg; - op->u.reg.rclass = RegClass_GPR; - op->u.reg.object = expr.object; - op->u.reg.num = expr.reg; - ia->argcount++; - op++; - } - } - - if (expr.label) { - if (expr.x18) { - op->type = IAOpnd_LabDiff; - op->negated = 0; - op->u.labdiff.label1 = expr.label; - op->u.labdiff.label2 = expr.x18; - op->u.labdiff.offset = expr.value; - } else { - PPCError_Error(PPCErrorStr125, expr.label->name->name); - } - } else { - op->type = IAOpnd_Imm; - op->u.imm.value = InlineAsm_GetExprValue(&expr); - } -} - -static void registeroperand(IAOperand *op, char rclass, short effect) { - IARegister *reg; - Object *obj; - - if (tk == TK_IDENTIFIER && (reg = InlineAsm_LookupRegisterPPCName(tkidentifier)) && reg->rclass == rclass) { - SInt32 num; - obj = reg->object; - num = reg->num; - op->type = IAOpnd_Reg; - op->u.reg.rclass = rclass; - op->u.reg.object = obj; - op->u.reg.num = num; - op->u.reg.effect = effect; - if (obj) { - reg->object->flags |= OBJECT_USED; - Registers_GetVarInfo(obj)->flags |= VarInfoFlag40; - } - } else if (rclass == RegClass_CRFIELD) { - op->type = IAOpnd_Reg; - op->u.reg.rclass = RegClass_CRFIELD; - op->u.reg.object = NULL; - op->u.reg.num = getimmediateoperand(0, 7); - op->u.reg.effect = effect; - return; - } else if (rclass == RegClass_SPR) { - op->type = IAOpnd_Reg; - op->u.reg.rclass = RegClass_SPR; - op->u.reg.object = NULL; - op->u.reg.num = getimmediateoperand(0, 1024); - op->u.reg.effect = effect; - return; - } else if (tk == '%' && InlineAsm_gccmode) { - SInt32 num; - tk = lex(); - if (tk != TK_INTCONST) { - CError_Error(CErrorStr144); - } else { - num = ExtractValue(tkintconst); - if (num < 0) - CError_Error(CErrorStr144); - } - - op->type = IAOpnd_6; - op->u.unk6.num = num; - op->u.unk6.unk4 = 2; - op->u.unk6.effect = effect; - op->u.unk6.rclass = rclass; - tk = lex(); - return; - } else if (tk == TK_IDENTIFIER) { - NotInRegisterError(tkidentifier->name, rclass); - } else { - PPCError_Error(PPCErrorStr171); - } - - tk = lex(); - if (!strcmp(tkidentifier->name, "@loword")) { - tk = lex(); - } else if (!strcmp(tkidentifier->name, "@hiword")) { - if (reg->object) - op->u.reg.num = 1; - else - PPCError_Error(PPCErrorStr168); - tk = lex(); - } else if (rclass == RegClass_GPR) { - if (reg->object && reg->object->type->size == 8) { - HashNameNode *name = reg->object->name; - PPCError_Error(PPCErrorStr127, name->name, name->name, name->name); - } - } -} - -static void cr0_operand(IAOperand *op, short effect) { - IARegister *reg; - - if ((reg = InlineAsm_LookupRegisterPPC("cr0"))) { - op->type = IAOpnd_Reg; - op->u.reg.rclass = RegClass_CRFIELD; - op->u.reg.object = reg->object; - op->u.reg.num = reg->num; - op->u.reg.effect = effect; - } else { - NotInRegisterError("cr0", RegClass_CRFIELD); - } -} - -static void r0_operand(IAOperand *op) { - IARegister *reg; - - if ((reg = InlineAsm_LookupRegisterPPC("r0"))) { - op->type = IAOpnd_Reg; - op->u.reg.rclass = RegClass_GPR; - op->u.reg.object = reg->object; - op->u.reg.num = reg->num; - op->u.reg.effect = 0; - tk = lex(); - } else { - NotInRegisterError("r0", RegClass_GPR); - } -} - -static void labeloperand(InlineAsm *ia, IAOperand *op, Boolean flag1, Boolean flag2, Boolean flag3) { - IALookupResult result; - - if (tk == TK_IDENTIFIER) { - if (!InlineAsm_LookupSymbol(tkidentifier, &result)) - result.label = InlineAsm_DeclareLabel(tkidentifier); - - if (result.label) { - op->type = IAOpnd_Lab; - op->u.lab.label = result.label; - } else if (result.object && result.object->datatype == DFUNC) { - if (flag3) - ia->flags |= IAFlag2; - op->type = IAOpnd_3; - op->u.obj.obj = result.object; - op->u.obj.offset = 0; - - if (flag1) { - op->u.obj.unk = IAExpr_4; - if (flag2) - CError_Error(CErrorStr261); - } else { - op->u.obj.unk = IAExpr_2; - if (flag2) - op->u.obj.unk = IAExpr_10; - op->u.obj.unk = IAExpr_6; - PPCError_Error(PPCErrorStr180); - } - } else { - CError_Error(CErrorStr144); - } - - tk = lex(); - } else if (tk == '*') { - if (!flag2) { - tk = lex(); - if (tk == '+') { - tk = lex(); - if (flag1) - immediateoperand(op, -0x2000000, 0x1FFFFFF); - else - immediateoperand(op, -0x8000, 0xFFFF); - } else if (tk == '-') { - tk = lex(); - op->u.imm.value = flag1 ? -immediatevalue(op, -0x1FFFFFF, 0x2000000) : -immediatevalue(op, -0x7FFF, 0x10000); - } else { - CError_Error(CErrorStr144); - } - } else { - CError_Error(CErrorStr144); - } - } else { - if (flag2) { - if (flag1) - immediateoperand(op, -0x2000000, 0x1FFFFFF); - else - immediateoperand(op, -0x8000, 0xFFFF); - } else { - CError_Error(CErrorStr144); - } - } -} - -static void imm_or_labeldiff_operand(InlineAsm *ia, IAOperand *op, SInt32 minimum, SInt32 maximum, Boolean negate) { - IAExpr expr; - Object *obj; - SInt32 value; - - InlineAsm_ExpressionPPC(&expr, 0); - - if ((obj = expr.xC) && !expr.x10 && expr.type == IAExpr_5 && obj->datatype == DDATA && IS_TYPE_INT_OR_ENUM(obj->type) && (obj->qual & Q_INLINE_DATA)) { - switch (ia->opcode) { - case PC_ADDI: - case PC_ADDIC: - case PC_ADDICR: - case PC_ADDIS: - case PC_ORI: - case PC_ORIS: - if (ia->args[1].u.imm.value) { - SInt32 cmp; - if (obj->datatype != DLOCAL) { - cmp = copts.codegen_pic ? INVALID_PIC_REG : NO_REG; - } else { - cmp = local_base_register(obj); - } - if (ia->args[1].u.imm.value == cmp) - break; - } - case PC_LI: - case PC_LIS: - case PC_TWI: - case PC_OPWORD: - InlineAsm_InitExpr5(&expr, expr.value + CInt64_GetULong(&obj->u.data.u.intconst)); - break; - } - } - - if (expr.label) { - if (expr.x18) { - op->type = IAOpnd_LabDiff; - if (negate) - op->negated = 1; - else - op->negated = 0; - op->u.labdiff.label1 = expr.label; - op->u.labdiff.label2 = expr.x18; - op->u.labdiff.offset = expr.value; - } else { - PPCError_Error(PPCErrorStr125, expr.label->name->name); - } - return; - } - - if (expr.xC) { - if (!expr.x10) { - if (ia->opcode != PC_OPWORD && expr.type == IAExpr_5) { - IllegalObjectInConst(&expr); - return; - } - - if (expr.xC->datatype == DLOCAL) { - op->type = IAOpnd_4; - op->u.obj.unk = IAExpr_1; - } else { - op->type = IAOpnd_3; - if (expr.type == IAExpr_5) { - expr.type = IAExpr_6; - PPCError_Error(PPCErrorStr180); - } - op->u.obj.unk = expr.type; - } - op->u.obj.obj = expr.xC; - op->u.obj.offset = expr.value; - } else { - PPCError_Error(PPCErrorStr123, expr.xC->name->name, expr.x10->name->name); - } - return; - } - - value = InlineAsm_GetExprValue(&expr); - if (value < minimum || value > maximum) - CError_Error(CErrorStr154); - - op->type = IAOpnd_Imm; - if (negate) - op->u.imm.value = -value; - else - op->u.imm.value = value; -} - -static void eatcommatoken(void) { - if (tk == ',') - tk = lex(); - else - CError_Error(CErrorStr116); -} - -static InlineAsm *InlineAsm_ScanAssemblyOperands(IAMnemonic *mnemonic) { - OpcodeInfo *info; - InlineAsm *ia; - SInt32 buffersize; - IAOperand *op; - int argcount; - char *format; - IARegister *reg; - - char code; - short effect; - Boolean has_excl; - Boolean has_question; - Boolean negate; - UInt32 t; - - info = &opcodeinfo[mnemonic->x4]; - argcount = info->x8; - if (PCODE_FLAG_SET_F(info) & fCanSetRecordBit) - argcount++; - if (!(PCODE_FLAG_SET_F(info) & fSetsCarry) && (PCODE_FLAG_SET_F(info) & fCanSetCarry)) - argcount++; - if (PCODE_FLAG_SET_T(info) & fCanLink) - argcount++; - - buffersize = sizeof(InlineAsm) + sizeof(IAOperand) * argcount; - ia = galloc(buffersize); - memset(ia, 0, buffersize); - - ia->opcode = mnemonic->x4; - ia->flags = 0; - ia->argcount = 0; - - op = ia->args; - for (format = mnemonic->format; *format; format++) { - CError_ASSERT(1664, ia->argcount < argcount); - - if (*format == ',') { - eatcommatoken(); - format++; - } else if (*format == ';') { - format++; - } - - if (*format == '[' || *format == '(') - format++; - - effect = EffectRead; - has_excl = 0; - has_question = 0; - negate = 0; - if (*format == '=') { - effect = EffectWrite; - format++; - } else if (*format == '+') { - effect = EffectRead | EffectWrite; - format++; - } - - if (*format == '-') { - negate = 1; - format++; - } - - if (*format == '?') { - has_question = 1; - format++; - } - - if (*format == '!') { - has_excl = 1; - format++; - } - - switch (*format) { - case 'p': - continue; - case '&': - if (format[1] == '2') { - op[0] = op[-2]; - format++; - if (op->type == IAOpnd_Reg) - op->u.reg.effect = effect; - ia->argcount++; - - op[1] = op[-1]; - op++; - if (op->type == IAOpnd_Reg) - op->u.reg.effect = effect; - } else { - op[0] = op[-1]; - if (op->type == IAOpnd_Reg) - op->u.reg.effect = effect; - } - break; - - case '%': { - SInt32 value; - format += pcode_const_from_format(format + 1, &value); - op->type = IAOpnd_Imm; - op->u.imm.value = value; - break; - } - - case 'b': - if (!isregisteroperand(RegClass_GPR)) { - if (tk == TK_INTCONST && tkintconst.lo == 0) - r0_operand(op); - } else { - registeroperand(op, RegClass_GPR, effect); - if (op->u.reg.object == NULL && op->u.reg.num == 0) - op->u.reg.effect = 0; - } - break; - - case 'r': - registeroperand(op, RegClass_GPR, effect); - break; - - case 'B': - case 'a': - case 'i': - case 't': - case 'u': - case 'x': - { - SInt32 value, hi, lo; - code = *format; - value = 16; - if (code == 'a') { - if (isdigit(format[1])) - code = *(++format); - else - CError_FATAL(1804); - } - - if (isdigit(format[1])) { - format += pcode_const_from_format(format + 1, &value); - } else if (code == 't' || code == 'B') { - code = 'u'; - value = 5; - } - - pcode_get_hi_lo(value, code, &hi, &lo); - if (!has_question || tk == ',') { - if (has_question) - tk = lex(); - if (has_excl) - getimmediateoperand(lo, hi); - else - immediateoperand(op, lo, hi); - } else { - op->type = IAOpnd_Imm; - op->u.imm.value = 0; - } - - if (code == 'i' && value == 16) - op->u.imm.value = (short) op->u.imm.value; - if (negate) - op->u.imm.value = -op->u.imm.value; - - if (pcode_check_imm_bits(op->u.imm.value, value, code)) - CError_FATAL(1838); - - break; - } - - case 'O': - if (tk == TK_INTCONST && tkintconst.lo == 0) { - getimmediateoperand(0, 0); - eatcommatoken(); - } - continue; - - case 'f': - registeroperand(op, RegClass_FPR, effect); - break; - - case 'v': - registeroperand(op, RegClass_VR, effect); - break; - - case 'T': - if (!has_question || tk == ',') { - if (has_question) - tk = lex(); - - immediateoperand(op, 268, 269); - if (op->u.reg.num == 268) - op->u.reg.num = 284; - else - op->u.reg.num = 285; - } else { - op->u.reg.num = 284; - } - - op->type = IAOpnd_Reg; - op->u.reg.rclass = RegClass_SPR; - op->u.reg.effect = effect; - break; - - case 'S': - { - SInt32 value; - format += pcode_const_from_format(format + 1, &value); - op->type = IAOpnd_Reg; - op->u.reg.rclass = RegClass_SPR; - op->u.reg.num = value; - op->u.reg.effect = effect; - break; - } - - case 'c': - if (has_question) { - if (isregisteroperand(RegClass_CRFIELD) || tk == TK_INTCONST) { - registeroperand(op, RegClass_CRFIELD, effect); - } else { - cr0_operand(op, effect); - if (format[1] == ',') - format++; - } - } else { - registeroperand(op, RegClass_CRFIELD, effect); - } - break; - - case 'l': - switch (ia->opcode) { - case PC_B: - case PC_BL: - labeloperand(ia, op, 1, mnemonic->x10 & 2, mnemonic->x10 & 1); - break; - default: - labeloperand(ia, op, 0, mnemonic->x10 & 2, mnemonic->x10 & 1); - break; - } - break; - - case 'w': - imm_or_labeldiff_operand(ia, op, -0x80000000, 0x7FFFFFFF, negate); - break; - - case 'M': - case 'm': - case 'n': - imm_or_labeldiff_operand(ia, op, -0x8000, 0xFFFF, negate); - break; - - case 'Q': - { - SInt32 cr = crbitoperand(); - op->type = IAOpnd_Reg; - op->u.reg.num = cr >> 2; - op->u.reg.rclass = RegClass_CRFIELD; - op->u.reg.effect = effect; - - ia->argcount++; - op[1].type = IAOpnd_Imm; - op[1].u.imm.value = cr % 4; - op++; - break; - } - - case 'd': { - short effect2; - CError_ASSERT(1971, format[1] == '('); - format++; - effect2 = EffectRead; - if (format[1] == '=') { - effect2 = EffectWrite; - format++; - } else if (format[1] == '+') { - effect2 = EffectRead | EffectWrite; - format++; - } - - CError_ASSERT(1983, format[1] == 'b'); - CError_ASSERT(1985, format[2] == ')'); - format += 2; - - switch (ia->opcode) { - case PC_LFS: - if (tk == TK_FLOATCONST) - floatoperand(op, ia, TYPE(&stfloat)); - else - memoryoperand(op, ia, 1, effect2); - break; - case PC_LFD: - if (tk == TK_FLOATCONST) - floatoperand(op, ia, TYPE(&stdouble)); - else - memoryoperand(op, ia, 1, effect2); - break; - default: - memoryoperand(op, ia, 1, effect2); - } - - break; - } - - case 'N': - immediateoperand(op, 1, 32); - break; - - case 's': - registeroperand(op, RegClass_SPR, effect); - break; - - case 'D': - if (tk == TK_IDENTIFIER && (reg = InlineAsm_LookupDCRRegister(tkidentifier->name))) { - op->type = IAOpnd_Imm; - op->u.imm.value = reg->num; - } else { - immediateoperand(op, 0, 1023); - } - break; - - case 'Y': - { - SInt32 mask = 255; - SInt32 i; - if (ia->opcode == PC_MTCRF) { - if (ia->args[0].type != IAOpnd_Imm) - CError_Error(CErrorStr144); - mask = ia->args[0].u.imm.value; - } - for (i = 0; i < 8; i++) { - if ((0x80 >> i) & mask) { - op->type = IAOpnd_Reg; - op->u.reg.num = i; - op->u.reg.rclass = RegClass_CRFIELD; - op->u.reg.effect = effect; - ia->argcount++; - op++; - } - } - ia->argcount--; - op--; - break; - } - - case 'P': - op->type = IAOpnd_Reg; - op->u.reg.rclass = RegClass_SPR; - op->u.reg.object = NULL; - if (format[1] == '3') { - format++; - op->u.reg.num = getimmediateoperand(0, 7); - } else { - op->u.reg.num = getimmediateoperand(0, 3); - } - op->u.reg.effect = effect; - break; - - case 'C': - op->type = IAOpnd_Reg; - op->u.reg.rclass = RegClass_SPR; - op->u.reg.object = NULL; - op->u.reg.num = 9; - op->u.reg.effect = effect; - break; - - case 'L': - op->type = IAOpnd_Reg; - op->u.reg.rclass = RegClass_SPR; - op->u.reg.object = NULL; - op->u.reg.num = 8; - op->u.reg.effect = effect; - break; - - case 'X': - op->type = IAOpnd_Reg; - op->u.reg.rclass = RegClass_SPR; - op->u.reg.object = NULL; - op->u.reg.num = 1; - op->u.reg.effect = effect; - break; - - case 'Z': - op->type = IAOpnd_Reg; - op->u.reg.rclass = RegClass_CRFIELD; - op->u.reg.object = NULL; - t = info->flags & 0xC0000000; - if (t == 0x40000000) { - op->u.reg.num = 1; - } else if (t == 0xC0000000) { - op->u.reg.num = 6; - } else { - op->u.reg.num = 0; - } - op->u.reg.effect = effect; - break; - - default: - CError_FATAL(2266); - } - - while (format[1] && strchr("/<>|*", format[1])) { - int index; - SInt32 value; - SInt32 value2; - IAOperand tmp; - switch ((code = *(++format))) { - case '/': - index = -1; - if (format[1] == '2') { - index = -2; - format++; - } - - tmp = op[index]; - op[index] = op[0]; - op[0] = tmp; - break; - case '*': - case '<': - case '>': - case '|': - if (op->type == IAOpnd_Imm) - value = op->u.imm.value; - else if (op->type == IAOpnd_Reg) - value = op->u.reg.num; - else - CError_FATAL(2312); - - if (format[1] == 'p') { - format++; - if (op[-1].type == IAOpnd_Imm) - value2 = op[-1].u.imm.value; - else if (op[-1].type == IAOpnd_Reg) - value2 = op[-1].u.reg.num; - else - CError_FATAL(2322); - } else if (isdigit(format[1])) { - format += pcode_const_from_format(format + 1, &value2); - } else { - CError_FATAL(2327); - } - - switch (code) { - case '<': - value = value2 - value; - break; - case '>': - value = value - value2; - break; - case '|': - value = value + value2; - break; - case '*': - value = value * value2; - break; - default: - CError_FATAL(2348); - } - - if (op->type == IAOpnd_Imm) - op->u.imm.value = value; - else if (op->type == IAOpnd_Reg) - op->u.reg.num = value; - else - CError_FATAL(2355); - break; - } - } - - ia->argcount++; - op++; - if (format[1] == ']' || format[1] == ')') - format++; - } - - return ia; -} - -static int mnemonic_has_overflow(char *buf) { - int result = 0; - - if (buf[strlen(buf) - 1] == 'o') { - if (!strcmp(buf, "bso")) - return 0; - if (!strcmp(buf, "fcmpo")) - return 0; - if (!strcmp(buf, "eieio")) - return 0; - if (!strcmp(buf, "vslo")) - return 0; - if (!strcmp(buf, "vsro")) - return 0; - result = 1; - } - - return result; -} - -static int mnemonic_has_absolute(const char *buf) { - int result = 0; - char last = buf[strlen(buf) - 1]; - - if (buf[0] == 'b' && last == 'a') - result = 1; - - return result; -} - -static int mnemonic_has_linkregister(const char *buf) { - int result = 0; - char last = buf[strlen(buf) - 1]; - - if (buf[0] == 'b' && last == 'l') - result = 1; - - return result; -} - -static int mnemonic_has_record(char *buf) { - int result = 0; - - if (lookahead() == '.') { - tk = lex(); - result = 1; - strcat(buf, "."); - } - - return result; -} - -static void installregistervariables(void) { -} - -void InlineAsm_InitializePPC(void) { - Test_Version_Numbers(); - allow_array_expressions = 1; - supports_hardware_fpu = 1; - assembledinstructions = 0; - - switch (copts.processor) { - case CPU_PPC401: cpu = CPUMask_401; break; - case CPU_PPC403: cpu = CPUMask_403; break; - case CPU_PPC505: cpu = CPUMask_50x; break; - case CPU_PPC509: cpu = CPUMask_50x; break; - case CPU_PPC555: cpu = CPUMask_55x_56x; break; - case CPU_PPC556: cpu = CPUMask_55x_56x; break; - case CPU_PPC565: cpu = CPUMask_55x_56x; break; - case CPU_PPC601: cpu = CPUMask_601; break; - case CPU_PPC602: cpu = CPUMask_602; break; - case CPU_PPC8240: cpu = CPUMask_8240; break; - case CPU_PPC8260: cpu = CPUMask_8260; break; - case CPU_PPC603: cpu = CPUMask_603; break; - case CPU_PPC603e: cpu = CPUMask_603; break; - case CPU_PPC604: cpu = CPUMask_604; break; - case CPU_PPC604e: cpu = CPUMask_604; break; - case CPU_PPC740: cpu = CPUMask_740_750; break; - case CPU_PPC750: cpu = CPUMask_740_750; break; - case CPU_PPC801: cpu = CPUMask_801_821_860; break; - case CPU_PPC821: cpu = CPUMask_801_821_860; break; - case CPU_PPC823: cpu = CPUMask_823_850; break; - case CPU_PPC850: cpu = CPUMask_823_850; break; - case CPU_PPC860: cpu = CPUMask_801_821_860; break; - case CPU_PPC7400: case CPU_PPC7450: cpu = CPUMask_74xx; break; - case CPU_Generic: cpu = CPUMask_Generic; break; - default: - CError_FATAL(2613); - } - - if (copts.altivec_model) - cpu |= 0x40000000; -} - -void InlineAsm_Initialize(AssemblerType assemblertype) { - assembler_type = assemblertype; - - if (assembler_type == 0) { - InlineAsm_InitializePPC(); - pic_base_reg = INVALID_PIC_REG; - } else { - pic_base_reg = 0; - pic_base_label = NULL; - } - - InlineAsm_InitializeMnemonicsPPC(); - InlineAsm_InitializeRegisters(); - InlineAsm_InitializeRegistersPPC(); - - if (assembler_type == 0) { - installregistervariables(); - } else { - process_arguments(setup_assembly_argument, 0); - assign_local_addresses(); - } -} - -static IAEntryPoint *InlineAsm_CreateEntryPoint(HashNameNode *name, Boolean flag) { - Object *obj; - IAEntryPoint *ep; - IALookupResult result; - - if (InlineAsm_LookupSymbol(name, &result) && (obj = result.object)) { - if (!(obj->datatype == DFUNC && !(obj->flags & OBJECT_DEFINED))) - CError_Error(CErrorStr122, name->name); - - obj->flags |= OBJECT_DEFINED; - obj->sclass = flag ? TK_STATIC : TK_EXTERN; - - ep = lalloc(sizeof(IAEntryPoint)); - memclrw(ep, sizeof(IAEntryPoint)); - ep->x0 = IADirective_Entry; - ep->x2 = 1; - ep->x8 = obj; - ep->size = assembledinstructions * 4; - } else { - CError_Error(CErrorStr140, name->name); - } - - return ep; -} - -static InlineAsm *InlineAsm_CreateFrFree(void) { - InlineAsm *ia = lalloc(sizeof(InlineAsm)); - memclrw(ia, sizeof(InlineAsm)); - ia->opcode = IADirective_FrFree; - ia->flags = IAFlag1; - return ia; -} - -SInt32 InlineAsm_IsDirective(AssemblerType assemblertype) { - char *name; - SInt32 directive = IADirective_Null; - - if (tk == '.') - tk = lex(); - - if (tk == TK_IDENTIFIER) { - name = tkidentifier->name; - if (!strcmp(name, "machine")) { - directive = IADirective_Machine; - } else if (assemblertype == AssemblerType_1) { - if (!strcmp(name, "entry")) { - directive = IADirective_Entry; - } else if (!strcmp(name, "fralloc")) { - directive = IADirective_FrAlloc; - } else if (!strcmp(name, "nofralloc")) { - directive = IADirective_NoFrAlloc; - } else if (!strcmp(name, "frfree")) { - directive = IADirective_FrFree; - } else if (!strcmp(name, "smclass")) { - directive = IADirective_SmClass; - } else if (!strcmp(name, "picbase")) { - directive = IADirective_PicBase; - } else { - directive = IADirective_Null; - } - } - } - - return directive; -} - -void InlineAsm_ProcessDirective(SInt32 directive) { - Boolean flag; - Statement *stmt; - IAOperand op; - - switch (directive) { - case IADirective_Entry: - flag = 0; - tk = lex(); - if (tk == TK_STATIC) { - flag = 1; - tk = lex(); - } else if (tk == TK_EXTERN) { - tk = lex(); - } - - if (tk != TK_IDENTIFIER) - CError_Error(CErrorStr107); - - stmt = CFunc_AppendStatement(ST_ASM); - stmt->expr = NULL; - stmt->expr = (ENode *) InlineAsm_CreateEntryPoint(tkidentifier, flag); - stmt->sourceoffset = -1; - tk = lex(); - break; - - case IADirective_FrAlloc: - if (assembledinstructions) - CError_Error(CErrorStr166); - if (asm_alloc_flags[0]) - CError_Error(CErrorStr165); - if (asm_alloc_flags[1] || asm_alloc_flags[2]) - CError_Error(CErrorStr166); - - tk = lex(); - if (tk != TK_EOL && tk != ';') - fralloc_parameter_area_size = getimmediateoperand(0x20, 0x7FFE); - - requires_frame = 1; - asm_alloc_flags[0] = 1; - break; - - case IADirective_NoFrAlloc: - if (asm_alloc_flags[0] || asm_alloc_flags[1]) - CError_Error(CErrorStr165); - if (asm_alloc_flags[2]) - CError_Error(CErrorStr166); - if (assembledinstructions) - CError_Error(CErrorStr166); - tk = lex(); - - asm_alloc_flags[1] = 1; - user_responsible_for_frame = 1; - break; - - case IADirective_FrFree: - if (asm_alloc_flags[1] || asm_alloc_flags[2]) - CError_Error(CErrorStr166); - - asm_alloc_flags[2] = 1; - stmt = CFunc_AppendStatement(ST_ASM); - stmt->expr = NULL; - stmt->expr = (ENode *) InlineAsm_CreateFrFree(); - if (copts.filesyminfo) - stmt->sourceoffset = CPrep_GetFileOffsetInfo(&cparser_fileoffset); - else - stmt->sourceoffset = -1; - tk = lex(); - break; - - case IADirective_Machine: - tk = lex(); - if (tk == TK_INTCONST) { - switch (tkintconst.lo) { - case 401: cpu = CPUMask_401; break; - case 403: cpu = CPUMask_403; break; - case 505: cpu = CPUMask_50x; break; - case 509: cpu = CPUMask_50x; break; - case 555: cpu = CPUMask_55x_56x; break; - case 556: cpu = CPUMask_55x_56x; break; - case 565: cpu = CPUMask_55x_56x; break; - case 601: cpu = CPUMask_601; break; - case 602: cpu = CPUMask_602; break; - case 8240: cpu = CPUMask_8240; break; - case 8260: cpu = CPUMask_8260; break; - case 603: cpu = CPUMask_603; break; - case 604: cpu = CPUMask_604; break; - case 740: cpu = CPUMask_740_750; break; - case 750: cpu = CPUMask_740_750; break; - case 801: cpu = CPUMask_801_821_860; break; - case 821: cpu = CPUMask_801_821_860; break; - case 823: cpu = CPUMask_823_850; break; - case 850: cpu = CPUMask_823_850; break; - case 860: cpu = CPUMask_801_821_860; break; - case 7400: cpu = CPUMask_74xx; break; - default: - CError_Error(CErrorStr144); - } - } else if (tk == TK_IDENTIFIER) { - if (!strcmp(tkidentifier->name, "all")) { - cpu = CPUMask_All; - } else if (!strcmp(tkidentifier->name, "generic")) { - cpu = CPUMask_Generic; - } else if (!strcmp(tkidentifier->name, "603e")) { - cpu = CPUMask_603; - } else if (!strcmp(tkidentifier->name, "604e")) { - cpu = CPUMask_604; - } else if (!strcmp(tkidentifier->name, "PPC603e")) { - cpu = CPUMask_603; - } else if (!strcmp(tkidentifier->name, "PPC604e")) { - cpu = CPUMask_604; - } else if (!strcmp(tkidentifier->name, "altivec")) { - cpu = CPUMask_74xx; - } else { - CError_Error(CErrorStr144); - } - } else { - CError_Error(CErrorStr144); - } - tk = lex(); - break; - - case IADirective_SmClass: - tk = lex(); - if (tk == TK_IDENTIFIER) { - if (!strcmp(tkidentifier->name, "PR")) - sm_section = SECT_TEXT; - else - CError_Error(CErrorStr144); - } else { - CError_Error(CErrorStr144); - } - tk = lex(); - break; - - case IADirective_PicBase: - tk = lex(); - registeroperand(&op, RegClass_GPR, EffectRead); - - if (!(op.type == IAOpnd_Reg && op.u.reg.object == NULL)) - CError_Error(CErrorStr144); - - tk = lex(); - if (tk == TK_IDENTIFIER) { - savepicbase(op.u.reg.num, tkidentifier); - tk = lex(); - } else { - CError_Error(CErrorStr144); - } - break; - - default: - CError_Error(CErrorStr261); - } -} - -void InlineAsm_ScanAssemblyDirective(void) { - SInt32 directive; - - if ((directive = InlineAsm_IsDirective(assembler_type)) != IADirective_Null) - InlineAsm_ProcessDirective(directive); -} - -void InlineAsm_ScanAssemblyInstruction(void) { - Statement *stmt; - InlineAsm *ia; - IAMnemonic *mnemonic; - Boolean record_flag; - Boolean flag3; - Boolean flag4; - Boolean flag5; - Boolean flag1; - Boolean flag2; - SInt32 directive; - OpcodeInfo *info; - char buf[20]; - - flag1 = 0; - flag2 = 0; - if ((directive = InlineAsm_IsDirective(assembler_type)) != IADirective_Null) { - InlineAsm_ProcessDirective(directive); - return; - } - - stmt = CFunc_AppendStatement(ST_ASM); - stmt->expr = NULL; - if (copts.filesyminfo) - stmt->sourceoffset = CPrep_GetFileOffsetInfo(&cparser_fileoffset); - else - stmt->sourceoffset = -1; - - strncpy(buf, tkidentifier->name, sizeof(buf)); - record_flag = mnemonic_has_record(buf); - mnemonic = InlineAsm_LookupMnemonicPPC(buf); - if (!mnemonic) - CError_Error(CErrorStr261); - - info = &opcodeinfo[mnemonic->x4]; - flag3 = (FLAG_SET_F(info->flags) & fCanSetCarry) && (mnemonic->x10 & 0x400); - flag4 = (FLAG_SET_T(info->flags) & fCanBeAbsolute) && (mnemonic->x10 & 2); - flag5 = (FLAG_SET_T(info->flags) & fCanLink) && (mnemonic->x10 & 1); - - if ((cpu == CPUMask_Generic) && (cpu & CPUFLAG_LOW_MASK) != ((cpu & mnemonic->cpu) & CPUFLAG_LOW_MASK)) { - CError_Error(CErrorStr152); - } else if (((cpu & mnemonic->cpu) & CPUFLAG_LOW_MASK) == 0) { - CError_Error(CErrorStr152); - } else if ((mnemonic->cpu & CPUFLAG_10000000) && !(cpu & CPUFLAG_10000000)) { - CError_Error(CErrorStr152); - } else if ((mnemonic->cpu & CPUFLAG_8000000) && !(cpu & CPUFLAG_8000000)) { - CError_Error(CErrorStr152); - } else if ((mnemonic->cpu & CPUFLAG_2000000) && !(cpu & CPUFLAG_2000000)) { - CError_Error(CErrorStr152); - } else if ((mnemonic->cpu & CPUFLAG_4000000) && !(cpu & CPUFLAG_4000000)) { - CError_Error(CErrorStr152); - } else if ((mnemonic->cpu & CPUFLAG_1000000) && !(cpu & CPUFLAG_1000000)) { - CError_Error(CErrorStr152); - } else if ((mnemonic->cpu & CPUFLAG_40000000) && !(cpu & CPUFLAG_40000000)) { - CError_Error(CErrorStr152); - } else if ((mnemonic->cpu & CPUFLAG_20000000) && !(cpu & CPUFLAG_20000000)) { - CError_Error(CErrorStr152); - } else if ((mnemonic->cpu & CPUFLAG_800000) && !(cpu & CPUFLAG_800000)) { - CError_Error(CErrorStr152); - } - - tk = lex(); - if (tk == '+' || tk == '-') { - if ( - ((OPCODE_PART_1(mnemonic->x10) == 16) && (OPCODE_PART_2(mnemonic->x10) != 20)) || - ((OPCODE_PART_1(mnemonic->x10) == 19) && (OPCODE_PART_3(mnemonic->x10) == 528) && (OPCODE_PART_2(mnemonic->x10) != 20)) || - ((OPCODE_PART_1(mnemonic->x10) == 19) && (OPCODE_PART_3(mnemonic->x10) == 16) && (OPCODE_PART_2(mnemonic->x10) != 20)) - ) { - if (tk == '+') - flag1 = 1; - else if (tk == '-') - flag2 = 1; - tk = lex(); - } else { - CError_Error(CErrorStr120); - } - } - - stmt->expr = (ENode *) InlineAsm_ScanAssemblyOperands(mnemonic); - - ia = (InlineAsm *) stmt->expr; - if (record_flag) - ia->flags2 |= IAFlagsB_1; - if (flag3) - ia->flags2 |= IAFlagsB_2; - if (flag4) - ia->flags2 |= IAFlagsB_4; - if (flag5) - ia->flags2 |= IAFlagsB_8; - if (flag1) - ia->flags2 |= IAFlagsB_10; - if (flag2) - ia->flags2 |= IAFlagsB_20; - if (volatileasm) - ia->flags2 |= IAFlagsB_40; - - ++assembledinstructions; -} - -static PCode *InlineAsm_TranslateIRtoPCodePPC(InlineAsm *ia, int argcount, AssemblerType assemblertype) { - PCode *pc; - int index; - int extra_args; - int reg; - int newargcount; - SInt32 buffersize; - IAOperand *src; - PCodeArg *dest; - OpcodeInfo *info; - - info = &opcodeinfo[ia->opcode]; - index = 0; - extra_args = 0; - reg = 0; - - if ((PCODE_FLAG_SET_F(info) & fCanSetRecordBit) && !(PCODE_FLAG_SET_F(info) & fRecordBit)) - extra_args++; - - if (!(PCODE_FLAG_SET_F(info) & fSetsCarry) && (PCODE_FLAG_SET_F(info) & fCanSetCarry)) - extra_args++; - - if (argcount < ia->argcount) { - if ((argcount + extra_args) >= ia->argcount) { - extra_args -= (ia->argcount - argcount); - argcount = ia->argcount; - } else { - CError_FATAL(3317); - } - } - - if (ia->opcode == PC_B && ia->args[0].type == IAOpnd_Imm) - ia->flags2 |= IAFlagsB_40; - - if (ia->opcode == PC_TWI || ia->opcode == PC_TW || ia->opcode == PC_TRAP || ia->opcode == PC_SC) - ia->flags |= IAFlag2; - - if (ia->flags & IAFlag2) { - newargcount = argcount + branch_count_volatiles(); - if (copts.exceptions && current_statement && assembler_type == 0) - newargcount += countexceptionactionregisters(current_statement->dobjstack); - - buffersize = sizeof(PCode) + sizeof(PCodeArg) * (newargcount + extra_args); - pc = lalloc(buffersize); - memset(pc, 0, buffersize); - pc->argCount = newargcount; - } else if (ia->opcode == PC_STMW || ia->opcode == PC_LMW) { - reg = ia->args[0].u.reg.object ? OBJECT_REG(ia->args[0].u.reg.object) : ia->args[0].u.reg.num; - newargcount = argcount + (32 - reg); - - buffersize = sizeof(PCode) + sizeof(PCodeArg) * newargcount; - pc = lalloc(buffersize); - memset(pc, 0, buffersize); - pc->argCount = newargcount; - } else { - buffersize = sizeof(PCode) + sizeof(PCodeArg) * (argcount + extra_args); - pc = lalloc(buffersize); - memset(pc, 0, buffersize); - pc->argCount = (ia->argcount > argcount) ? ia->argcount : argcount; - } - - pc->op = ia->opcode; - pc->flags = info->flags; - pc->sourceoffset = current_statement ? current_statement->sourceoffset : -1; - - dest = pc->args; - src = ia->args; - argcount += extra_args; - while (index < argcount) { - if (index >= ia->argcount) { - dest->kind = PCOp_PLACEHOLDEROPERAND; - } else { - switch (src->type) { - case IAOpnd_0: - dest->kind = PCOp_PLACEHOLDEROPERAND; - break; - - case IAOpnd_Imm: - dest->kind = PCOp_IMMEDIATE; - dest->data.imm.value = src->u.imm.value; - if (pc->flags & (fIsRead | fIsWrite)) - pc->flags |= fIsPtrOp; - dest->data.imm.obj = NULL; - break; - - case IAOpnd_Reg: { - int r20; - r20 = 0; - if (src->u.reg.object) { - if (Registers_GetVarInfo(src->u.reg.object)->flags & VarInfoFlag2) { - if (src->u.reg.num == 1) - r20 = OBJECT_REG_HI(src->u.reg.object); - else - r20 = OBJECT_REG(src->u.reg.object); - } else { - if (Registers_GetVarInfo(src->u.reg.object)->flags & VarInfoFlag40) - PPCError_Error(PPCErrorStr172, src->u.reg.object->name->name); - else - PPCError_Error(PPCErrorStr167, src->u.reg.object->name->name); - } - } else if (src->u.reg.num == INVALID_PIC_REG) { - r20 = pic_base_reg; - } else { - r20 = src->u.reg.num; - } - - dest->kind = PCOp_REGISTER; - dest->arg = src->u.reg.rclass; - dest->data.reg.reg = r20; - dest->data.reg.effect = src->u.reg.effect; - if (pc->op == PC_RLWIMI && (dest->data.reg.effect & EffectWrite) && dest->arg == RegClass_GPR && !(dest->data.reg.effect & EffectRead)) - CError_FATAL(3442); - - if (dest->arg == RegClass_SPR) { - int i; - dest->kind = PCOp_SYSREG; - for (i = 0; i < 4; i++) { - if (dest->data.reg.reg == spr_to_sysreg[i]) { - dest->kind = PCOp_REGISTER; - dest->arg = RegClass_SPR; - dest->data.reg.reg = i; - break; - } - } - pcsetsideeffects(pc); - } else if (dest->arg == RegClass_6 || dest->arg == RegClass_DCR) { - short save = dest->data.reg.reg; - dest->kind = PCOp_IMMEDIATE; - dest->data.imm.value = save; - dest->data.imm.obj = NULL; - break; - } - - if ((src->u.reg.effect & EffectWrite) && dest->data.reg.reg < n_real_registers[dest->arg]) { - if (src->u.reg.object) { - if (Registers_GetVarInfo(src->u.reg.object)->flags & VarInfoFlag4) { - int reg, regHi; - CError_ASSERT(3474, dest->arg == RegClass_GPR); - - regHi = OBJECT_REG_HI(src->u.reg.object); - reg = OBJECT_REG(src->u.reg.object); - retain_GPR_pair(src->u.reg.object, reg, regHi); - } else { - retain_register(src->u.reg.object, dest->arg, dest->data.reg.reg); - } - } else { - retain_register(NULL, dest->arg, dest->data.reg.reg); - } - } - - break; - } - - case IAOpnd_Lab: - if (!src->u.lab.label->pclabel) - src->u.lab.label->pclabel = makepclabel(); - dest->kind = PCOp_LABEL; - dest->data.label.label = src->u.lab.label->pclabel; - break; - - case IAOpnd_3: - case IAOpnd_4: - dest->kind = PCOp_MEMORY; - dest->arg = src->u.obj.unk; - dest->data.mem.obj = src->u.obj.obj; - dest->data.mem.offset = src->u.obj.offset; - if (pc->flags & (fIsRead | fIsWrite | fPCodeFlag20000 | fPCodeFlag40000)) { - pc->alias = make_alias(dest->data.mem.obj, dest->data.mem.offset, nbytes_loaded_or_stored_by(pc)); - if (is_volatile_object(dest->data.mem.obj)) - pc->flags |= fIsVolatile; - if (OBJ_GET_TARGET_CONST(dest->data.mem.obj)) - pc->flags |= fIsConst; - } - break; - - case IAOpnd_LabDiff: - if (src->u.labdiff.label1->pclabel == NULL) - src->u.labdiff.label1->pclabel = makepclabel(); - if (src->u.labdiff.label2->pclabel == NULL) - src->u.labdiff.label2->pclabel = makepclabel(); - if (pc->flags & (fIsRead | fIsWrite)) - pc->flags |= fIsPtrOp; - dest->kind = PCOp_LABELDIFF; - dest->data.labeldiff.labelA = src->u.labdiff.label1->pclabel; - dest->data.labeldiff.labelB = src->u.labdiff.label2->pclabel; - dest->arg = src->negated; - dest->data.labeldiff.offset = src->u.labdiff.offset; - break; - - default: - CError_FATAL(3528); - } - } - - index++; - dest++; - src++; - } - - if (ia->opcode == PC_STMW || ia->opcode == PC_LMW) { - int i; - for (i = reg; i < 32; i++, dest++) { - dest->kind = PCOp_REGISTER; - dest->arg = RegClass_GPR; - dest->data.reg.reg = i; - dest->data.reg.effect = ((ia->opcode == PC_LMW) ? EffectWrite : EffectRead); - } - } - - if (ia->flags & IAFlag2) { - UInt32 masks[5] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; - branch_record_volatiles(dest, masks); - if (copts.exceptions && current_statement && assembler_type == 0) - noteexceptionactionregisters(current_statement->dobjstack, dest); - } - - return pc; -} - -void InlineAsm_TranslateIRtoPCode(Statement *stmt) { - InlineAsm *ia; - PCode *pc; - - ia = (InlineAsm *) stmt->expr; - pc = InlineAsm_TranslateIRtoPCodePPC(ia, opcodeinfo[ia->opcode].x8, assembler_type); - appendpcode(pclastblock, pc); - - if ((ia->flags2 & IAFlagsB_40) || !copts.optimizewithasm) - setpcodeflags(fSideEffects); - - if (ia->flags2 & IAFlagsB_1) { - if (PCODE_FLAG_SET_F(pc) & fCanSetRecordBit) - pcsetrecordbit(pclastblock->lastPCode); - else - CError_Error(CErrorStr261); - } - - if (ia->flags2 & IAFlagsB_2) { - if (PCODE_FLAG_SET_F(pc) & fCanSetCarry) - setpcodeflags(fOverflow); // idk? - else - CError_Error(CErrorStr261); - } - - if (ia->flags2 & IAFlagsB_4) { - if (PCODE_FLAG_SET_T(pc) & fCanBeAbsolute) { - int i; - for (i = 0; i < pc->argCount; i++) { - if (pc->args[i].kind == PCOp_LABEL || pc->args[i].kind == PCOp_MEMORY) { - PPCError_Error(PPCErrorStr177); - break; - } - } - setpcodeflags(fAbsolute); - } else { - CError_Error(CErrorStr261); - } - } - - if (ia->flags2 & IAFlagsB_8) { - if (PCODE_FLAG_SET_T(pc) & fCanLink) { - pcsetlinkbit(pclastblock->lastPCode); - if (!(ia->flags & IAFlag2)) { - pclastblock->lastPCode->flags &= ~fIsCall; - pclastblock->lastPCode->flags |= fIsBranch; - } - makes_call = 1; - } else { - CError_Error(CErrorStr261); - } - } - - if (ia->flags2 & IAFlagsB_10) - setpcodeflags(fCanSetRecordBit); - if (ia->flags2 & IAFlagsB_20) - setpcodeflags(fCanSetCarry); - - if (OPCODE_PART_1(opcodeinfo[pc->op].insn) == 16) { - PCodeLabel *dest = NULL; - PCodeLabel *src = makepclabel(); - switch (pc->op) { - case PC_BC: - if (pc->args[3].kind == PCOp_LABEL) - dest = pc->args[3].data.label.label; - break; - case PC_BT: - case PC_BF: - case PC_BDNZT: - case PC_BDNZF: - case PC_BDZT: - case PC_BDZF: - if (pc->args[2].kind == PCOp_LABEL) - dest = pc->args[2].data.label.label; - break; - case PC_BDNZ: - case PC_BDZ: - if (pc->args[0].kind == PCOp_LABEL) - dest = pc->args[0].data.label.label; - break; - default: - CError_FATAL(3715); - } - - if (dest) { - pcbranch(pclastblock, dest); - pcbranch(pclastblock, src); - makepcblock(); - pclabel(pclastblock, src); - } - return; - } - - if (OPCODE_PART_1(opcodeinfo[pc->op].insn) == 18) { - PCodeLabel *label; - if (ia->flags2 & IAFlagsB_8) { - label = makepclabel(); - pcbranch(pclastblock, label); - } - if (pc->args[0].kind == PCOp_LABEL) - pcbranch(pclastblock, pc->args[0].data.label.label); - makepcblock(); - if (ia->flags2 & IAFlagsB_8) { - pclabel(pclastblock, label); - } - return; - } - - if (OPCODE_PART_1(opcodeinfo[pc->op].insn) == 19) { - switch (pc->op) { - case PC_BLR: - case PC_RFI: - if (asm_alloc_flags[3]) - asm_alloc_flags[9] = 1; - else - asm_alloc_flags[8] = 1; - - if (asm_alloc_flags[4]) - asm_alloc_flags[5] = 1; - - if (pc->op == PC_BLR) - asm_alloc_flags[6] = 1; - else - asm_alloc_flags[7] = 1; - break; - } - } -} - -const char *InlineAsm_GetMnemonic(InlineAsm *ia) { - return opcodeinfo[ia->opcode].name; -} - -static void savepicbase(short reg, HashNameNode *name) { - IALookupResult result; - - if (!InlineAsm_LookupSymbol(name, &result)) - result.label = InlineAsm_DeclareLabel(name); - - pic_base_label = result.label; - pic_base_reg = reg; - uses_globals = 1; -} - -static SInt32 InlineAsm_OpcodeSize(InlineAsm *ia) { - if (opcodeinfo[ia->opcode].flags & (fIsRead | fIsWrite)) { - switch (ia->opcode) { - case PC_LBZ: - case PC_LBZU: - case PC_LBZX: - case PC_LBZUX: - case PC_STB: - case PC_STBU: - case PC_STBX: - case PC_STBUX: - return 1; - case PC_LHZ: - case PC_LHZU: - case PC_LHZX: - case PC_LHZUX: - case PC_LHA: - case PC_LHAU: - case PC_LHAX: - case PC_LHAUX: - case PC_LHBRX: - case PC_STH: - case PC_STHU: - case PC_STHX: - case PC_STHUX: - case PC_STHBRX: - return 2; - case PC_LWZ: - case PC_LWZU: - case PC_LWZX: - case PC_LWZUX: - case PC_LWBRX: - case PC_STW: - case PC_STWU: - case PC_STWX: - case PC_STWUX: - case PC_STWBRX: - case PC_LFS: - case PC_LFSU: - case PC_LFSX: - case PC_LFSUX: - case PC_STFS: - case PC_STFSU: - case PC_STFSX: - case PC_STFSUX: - case PC_LWARX: - case PC_STFIWX: - case PC_STWCX: - case PC_ECIWX: - case PC_ECOWX: - case PC_MFROM: - case PC_LSCBX: - return 4; - case PC_LMW: - case PC_STMW: - if (ia->args[0].type == IAOpnd_Reg && ia->args[0].u.reg.object == NULL) - return (32 - ia->args[0].u.reg.num) * 4; - else - return 128; - case PC_LFD: - case PC_LFDU: - case PC_LFDX: - case PC_LFDUX: - case PC_STFD: - case PC_STFDU: - case PC_STFDX: - case PC_STFDUX: - return 8; - case PC_LSWI: - case PC_STSWI: - return ia->args[2].u.imm.value; - case PC_LSWX: - case PC_STSWX: - return 128; - case PC_LVEBX: - case PC_STVEBX: - return 1; - case PC_LVEHX: - case PC_STVEHX: - return 2; - case PC_LVEWX: - case PC_STVEWX: - return 4; - case PC_LVSL: - case PC_LVSR: - case PC_LVX: - case PC_LVXL: - case PC_STVX: - case PC_STVXL: - return 16; - default: - CError_FATAL(3924); - } - } else { - if (opcodeinfo[ia->opcode].flags & fOpTypeGPR) - return 4; - if (opcodeinfo[ia->opcode].flags & fOpTypeFPR) - return 8; - if (opcodeinfo[ia->opcode].flags & fOpTypeVR) - return 16; - - if (opcodeinfo[ia->opcode].flags & fSideEffects) { - switch (ia->opcode) { - case PC_TLBIE: - case PC_TLBLD: - case PC_TLBLI: - return 4; - default: - CError_FATAL(3941); - } - } - } - - CError_FATAL(3944); - return 0; -} - -void CodeGen_GetAsmEffects(Statement *stmt, IAEffects *effects) { - InlineAsm *ia; - OpcodeInfo *info; - int i; - IAOperand *op; - VarInfo *vi; - - ia = (InlineAsm *) stmt->expr; - info = &opcodeinfo[ia->opcode]; - - effects->numoperands = 0; - effects->numlabels = 0; - effects->x1 = 0; - effects->x2 = 0; - effects->x3 = 0; - effects->x4 = 0; - effects->x0 = 0; - effects->x5 = 0; - - if (info->flags & fIsPtrOp) { - if (info->flags & fIsRead) - effects->x1 = 1; - if (info->flags & fIsWrite) - effects->x2 = 1; - } - - if (PCODE_FLAG_SET_T(info) & fCanLink) { - if (ia->flags2 & IAFlagsB_8) - effects->x4 = 1; - else if ((info->flags & fIsCall) || (info->flags & fIsWrite)) - effects->x3 = 1; - - if (ia->opcode == PC_B) { - if (ia->args[0].type == IAOpnd_Imm) - effects->x0 = 1; - effects->x5 = 1; - } - } - - if (info->flags & fSideEffects) - effects->x0 = 1; - - if (ia->opcode == PC_BC && (ia->flags2 & IAFlagsB_8)) - effects->x4 = 1; - - for (i = 0, op = ia->args; i < ia->argcount; i++, op++) { - switch (op->type) { - case IAOpnd_0: - case IAOpnd_Imm: - break; - case IAOpnd_Reg: - if (op->u.reg.object) { - if ((vi = Registers_GetVarInfo(op->u.reg.object))) - vi->flags |= VarInfoFlag40; - if (op->u.reg.effect & EffectRead) { - if ( - TYPE_FITS_IN_REGISTER(op->u.reg.object->type) || - IS_TYPE_FLOAT(op->u.reg.object->type) || - IS_TYPE_VECTOR(op->u.reg.object->type) - ) { - effects->operands[effects->numoperands].type = IAEffect_0; - effects->operands[effects->numoperands].object = op->u.reg.object; - effects->operands[effects->numoperands].offset = 0; - effects->operands[effects->numoperands].size = op->u.reg.object->type->size; - effects->numoperands++; - } else { - CError_FATAL(4051); - } - } - } - break; - case IAOpnd_3: - case IAOpnd_4: - if (op->u.obj.obj) { - if (info->flags & fIsRead) { - effects->operands[effects->numoperands].type = IAEffect_0; - effects->operands[effects->numoperands].object = op->u.obj.obj; - effects->operands[effects->numoperands].offset = op->u.obj.offset; - effects->operands[effects->numoperands].size = InlineAsm_OpcodeSize(ia); - effects->numoperands++; - } else if (!(info->flags & (fIsBranch | fIsCall))) { - effects->operands[effects->numoperands].type = IAEffect_3; - effects->operands[effects->numoperands].object = op->u.obj.obj; - effects->operands[effects->numoperands].offset = op->u.obj.offset; - effects->operands[effects->numoperands].size = InlineAsm_OpcodeSize(ia); - effects->numoperands++; - } - } - break; - case IAOpnd_Lab: - effects->labels[effects->numlabels] = op->u.lab.label; - effects->numlabels++; - break; - case IAOpnd_LabDiff: - effects->labels[effects->numlabels] = op->u.labdiff.label1; - effects->numlabels++; - effects->labels[effects->numlabels] = op->u.labdiff.label2; - effects->numlabels++; - effects->x3 = 1; - break; - default: - CError_FATAL(4087); - } - - CError_ASSERT(4090, (UInt32) effects->numoperands <= IAMaxOperands); - CError_ASSERT(4093, (UInt32) effects->numlabels <= IAMaxLabels); - } - - for (i = 0, op = ia->args; i < ia->argcount; i++, op++) { - switch (op->type) { - case IAOpnd_Reg: - if (op->u.reg.object) { - if ((vi = Registers_GetVarInfo(op->u.reg.object))) - vi->flags |= VarInfoFlag40; - if (op->u.reg.effect & EffectWrite) { - if ( - TYPE_FITS_IN_REGISTER(op->u.reg.object->type) || - IS_TYPE_FLOAT(op->u.reg.object->type) || - IS_TYPE_VECTOR(op->u.reg.object->type) - ) { - effects->operands[effects->numoperands].type = IAEffect_1; - effects->operands[effects->numoperands].object = op->u.reg.object; - effects->operands[effects->numoperands].offset = 0; - effects->operands[effects->numoperands].size = op->u.reg.object->type->size; - effects->numoperands++; - } else { - CError_FATAL(4132); - } - } - } - break; - case IAOpnd_3: - case IAOpnd_4: - if (op->u.obj.obj) { - if (info->flags & fIsWrite) { - effects->operands[effects->numoperands].type = IAEffect_1; - effects->operands[effects->numoperands].object = op->u.obj.obj; - effects->operands[effects->numoperands].offset = op->u.obj.offset; - effects->operands[effects->numoperands].size = InlineAsm_OpcodeSize(ia); - effects->numoperands++; - } - } - break; - } - - CError_ASSERT(4151, (UInt32) effects->numoperands <= IAMaxOperands); - } - - if ((info->flags & (fIsBranch | fIsCall)) && (SInt32)effects->numlabels == 0) - effects->x3 = 1; -} - -void CodeGen_PropagateIntoAsm(Statement *stmt, Object *obj, ENode *expr) { - InlineAsm *ia; - Object *newobj; - - ia = (InlineAsm *) stmt->expr; - if (ENODE_IS(expr, EOBJREF)) { - newobj = expr->data.objref; - if (obj->otype == newobj->otype && obj->datatype == newobj->datatype) { - int i; - for (i = 0; i < ia->argcount; i++) { - switch (ia->args[i].type) { - case IAOpnd_Reg: - if (ia->args[i].u.reg.object == obj && - (ia->args[i].u.reg.effect & (EffectRead | EffectWrite)) == EffectRead) { - if (TYPE_FITS_IN_REGISTER(newobj->type) && - ia->args[i].u.reg.rclass == RegClass_GPR) { - ia->args[i].u.reg.object = newobj; - } else if (IS_TYPE_FLOAT(newobj->type) && - ia->args[i].u.reg.rclass == RegClass_FPR) { - ia->args[i].u.reg.object = newobj; - } else if (IS_TYPE_VECTOR(newobj->type) && - ia->args[i].u.reg.rclass == RegClass_VR) { - ia->args[i].u.reg.object = newobj; - } - } - break; - case IAOpnd_3: - case IAOpnd_4: - if (!(opcodeinfo[ia->opcode].flags & (fIsWrite | fPCodeFlag40000)) && - ia->args[i].u.obj.obj == obj) - ia->args[i].u.obj.obj = newobj; - break; - } - } - } - } -} - -Statement *CodeGen_CopyAsmStat(Statement *stmt) { - Statement *copy; - SInt32 size; - InlineAsm *ia; - InlineAsm *iacopy; - - copy = galloc(sizeof(Statement)); - *copy = *stmt; - - ia = (InlineAsm *) stmt->expr; - size = sizeof(InlineAsm) + sizeof(IAOperand) * ia->argcount; - iacopy = galloc(size); - memcpy(iacopy, ia, size); - copy->expr = (ENode *) iacopy; - - return copy; -} - |