diff options
Diffstat (limited to 'compiler_and_linker/unsorted/InlineAsm.c')
-rw-r--r-- | compiler_and_linker/unsorted/InlineAsm.c | 680 |
1 files changed, 0 insertions, 680 deletions
diff --git a/compiler_and_linker/unsorted/InlineAsm.c b/compiler_and_linker/unsorted/InlineAsm.c deleted file mode 100644 index 46a95d2..0000000 --- a/compiler_and_linker/unsorted/InlineAsm.c +++ /dev/null @@ -1,680 +0,0 @@ -#include "compiler/InlineAsm.h" -#include "compiler/InlineAsmPPC.h" -#include "compiler/GCCInlineAsm.h" -#include "compiler/CompilerTools.h" -#include "compiler/CError.h" -#include "compiler/CExpr.h" -#include "compiler/CFunc.h" -#include "compiler/CInit.h" -#include "compiler/CInline.h" -#include "compiler/CInt64.h" -#include "compiler/CMachine.h" -#include "compiler/COptimizer.h" -#include "compiler/CParser.h" -#include "compiler/CPrep.h" -#include "compiler/CPrepTokenizer.h" -#include "compiler/CScope.h" -#include "compiler/PCode.h" -#include "compiler/Registers.h" -#include "compiler/objects.h" -#include "compiler/scopes.h" -#include "compiler/types.h" - -int allow_array_expressions = 1; - -int backtracking; -jmp_buf backtrack; -jmp_buf InlineAsm_assemblererror; -static int ASMstmtnb; - -void AssemblerError(void) { - longjmp(InlineAsm_assemblererror, 1); -} - -void InlineAsm_SyntaxError(short code) { - if (backtracking) - longjmp(backtrack, 1); - - if (tk == TK_EOL || tk == ';') - code = CErrorStr112; - CError_Error(code); -} - -CLabel *InlineAsm_LookupLabel(HashNameNode *name) { - CLabel *label; - - for (label = Labels; label; label = label->next) { - if (name == label->name) - break; - } - - return label; -} - -CLabel *InlineAsm_DeclareLabel(HashNameNode *name) { - CLabel *label = newlabel(); - label->name = name; - label->next = Labels; - Labels = label; - return label; -} - -static void InlineAsm_DefineLabel(HashNameNode *name) { - CLabel *label; - Statement *stmt; - - label = InlineAsm_LookupLabel(name); - if (!label) { - label = InlineAsm_DeclareLabel(name); - } else { - if (label->stmt) - CError_Error(CErrorStr171, name->name); - } - - stmt = CFunc_AppendStatement(ST_LABEL); - stmt->label = label; - label->stmt = stmt; -} - -Boolean InlineAsm_LookupSymbolOrTag(HashNameNode *name, IALookupResult *result, Boolean allow_tag) { - ObjBase *obj; - NameSpace *nspace; - NameSpaceObjectList *list; - - result->name = name; - result->object = NULL; - result->label = NULL; - result->type = NULL; - result->has_value = 0; - - if ((result->label = InlineAsm_LookupLabel(name))) - return 1; - - for (nspace = cscope_current; nspace; nspace = nspace->parent) { - if ((list = CScope_FindName(nspace, name))) { - obj = list->object; - switch (obj->otype) { - case OT_ENUMCONST: - result->has_value = 1; - result->value = OBJ_ENUM_CONST(list->object)->val.lo; - return 1; - case OT_OBJECT: - if (OBJECT(obj)->datatype == DABSOLUTE) { - result->has_value = 1; - result->value = OBJECT(obj)->u.address; - } else { - if (OBJECT(obj)->datatype == DDATA && (OBJECT(obj)->qual & Q_INLINE_DATA)) - CInit_ExportConst(OBJECT(obj)); - result->object = OBJECT(obj); - } - return 1; - case OT_TYPE: - result->type = OBJ_TYPE(obj)->type; - return 1; - case OT_TYPETAG: - if (allow_tag) { - result->type = OBJ_TYPE_TAG(obj)->type; - return 1; - } - case OT_NAMESPACE: - case OT_MEMBERVAR: - return 0; - default: - CError_FATAL(245); - } - } - } - - return 0; -} - -Boolean InlineAsm_LookupSymbol(HashNameNode *name, IALookupResult *result) { - return InlineAsm_LookupSymbolOrTag(name, result, 0); -} - -static ObjMemberVar *isclassmember(TypeClass *tclass, HashNameNode *name) { - NameSpaceObjectList *list; - - list = CScope_FindName(tclass->nspace, name); - return (list && list->object->otype == OT_MEMBERVAR) ? OBJ_MEMBER_VAR(list->object) : NULL; -} - -SInt32 InlineAsm_StructMemberOffset(Type *type) { - StructMember *member; - ObjMemberVar *ivar; - SInt32 offset = 0; - - do { - if (IS_TYPE_STRUCT(type)) { - tk = lex(); - if (tk != TK_IDENTIFIER) - InlineAsm_SyntaxError(CErrorStr107); - member = ismember(TYPE_STRUCT(type), tkidentifier); - if (!member) - CError_Error(CErrorStr150, tkidentifier->name); - offset += member->offset; - type = member->type; - tk = lex(); - } else if (IS_TYPE_CLASS(type)) { - tk = lex(); - if (tk != TK_IDENTIFIER) - InlineAsm_SyntaxError(CErrorStr107); - ivar = isclassmember(TYPE_CLASS(type), tkidentifier); - if (!ivar) - CError_Error(CErrorStr150, tkidentifier->name); - offset += ivar->offset; - type = ivar->type; - tk = lex(); - } else { - CError_Error(CErrorStr149); - } - } while (tk == '.'); - - return offset; -} - -SInt32 InlineAsm_StructArrayMemberOffset(Type *type) { - StructMember *member; - ObjMemberVar *ivar; - SInt32 offset = 0; - - do { - if (tk == '.') { - if (IS_TYPE_STRUCT(type)) { - tk = lex(); - if (tk != TK_IDENTIFIER) - InlineAsm_SyntaxError(CErrorStr107); - member = ismember(TYPE_STRUCT(type), tkidentifier); - if (!member) - CError_Error(CErrorStr150, tkidentifier->name); - offset += member->offset; - type = member->type; - tk = lex(); - } else if (IS_TYPE_CLASS(type)) { - tk = lex(); - if (tk != TK_IDENTIFIER) - InlineAsm_SyntaxError(CErrorStr107); - ivar = isclassmember(TYPE_CLASS(type), tkidentifier); - if (!ivar) - CError_Error(CErrorStr150, tkidentifier->name); - offset += ivar->offset; - type = ivar->type; - tk = lex(); - } else { - CError_Error(CErrorStr149); - } - } else { - if (IS_TYPE_ARRAY(type)) { - type = TPTR_TARGET(type); - tk = lex(); - offset += type->size * InlineAsm_ConstantExpression(); - if (tk != ']') - InlineAsm_SyntaxError(125); - tk = lex(); - } else { - CError_Error(CErrorStr148); - } - } - } while (tk == '.' || tk == '['); - - return offset; -} - -SInt32 InlineAsm_StructPointerMemberOffset(Type *type) { - StructMember *member; - ObjMemberVar *ivar; - SInt32 offset; - - tk = lex(); - if (tk != TK_IDENTIFIER) - InlineAsm_SyntaxError(107); - - if (IS_TYPE_STRUCT(type)) { - member = ismember(TYPE_STRUCT(type), tkidentifier); - if (!member) - CError_Error(CErrorStr150, tkidentifier->name); - offset = member->offset; - type = member->type; - } else { - ivar = isclassmember(TYPE_CLASS(type), tkidentifier); - if (!ivar) - CError_Error(CErrorStr150, tkidentifier->name); - offset = ivar->offset; - type = ivar->type; - } - - tk = lex(); - if (tk == '.' || tk == '[') - offset += InlineAsm_StructArrayMemberOffset(type); - - return offset; -} - -static SInt32 DiadicOperator(SInt32 left, short op, SInt32 right) { - CInt64 left64; - CInt64 right64; - CInt64_SetLong(&left64, left); - CInt64_SetLong(&right64, right); - right64 = CMach_CalcIntDiadic(TYPE(&stsignedint), left64, op, right64); - return CInt64_GetULong(&right64); -} - -static SInt32 PrimaryExpression(void) { - IALookupResult result; - SInt32 value; - - switch (tk) { - case TK_IDENTIFIER: - if (InlineAsm_LookupSymbol(tkidentifier, &result)) { - if (result.has_value) { - tk = lex(); - return result.value; - } - - if (result.type && (IS_TYPE_STRUCT(result.type) || IS_TYPE_CLASS(result.type))) { - tk = lex(); - if (tk != '.') - InlineAsm_SyntaxError(120); - if (allow_array_expressions) - return InlineAsm_StructArrayMemberOffset(result.type); - else - return InlineAsm_StructMemberOffset(result.type); - } else { - InlineAsm_SyntaxError(124); - } - } else { - InlineAsm_SyntaxError(124); - } - break; - case TK_INTCONST: - value = tkintconst.lo; - tk = lex(); - return value; - case TK_SIZEOF: - return scansizeof(); - case '+': - tk = lex(); - return PrimaryExpression(); - case '-': - tk = lex(); - return -PrimaryExpression(); - case '!': - tk = lex(); - return PrimaryExpression() == 0; - case '~': - tk = lex(); - return ~PrimaryExpression(); - case '(': - tk = lex(); - value = InlineAsm_ConstantExpression(); - if (tk != ')') - InlineAsm_SyntaxError(115); - tk = lex(); - return value; - default: - InlineAsm_SyntaxError(120); - } - - return 0; -} - -static SInt32 ConstantExpressionTail(SInt32 value) { - SInt32 right; - short left_token; - short right_prec; - - while (1) { - left_token = tk; - tk = lex(); - right = PrimaryExpression(); - - right_prec = GetPrec(tk); - if (right_prec == 0) - return DiadicOperator(value, left_token, right); - - if (GetPrec(left_token) >= right_prec) { - value = DiadicOperator(value, left_token, right); - } else { - value = DiadicOperator(value, left_token, ConstantExpressionTail(right)); - if (GetPrec(tk) == 0) - return value; - } - } -} - -SInt32 InlineAsm_ConstantExpression(void) { - SInt32 value = PrimaryExpression(); - - if (GetPrec(tk) == 0) - return value; - else - return ConstantExpressionTail(value); -} - -HashNameNode *MakeLocalLabel(CInt64 num) { - char buf[80]; - sprintf(buf, "@%i_%i", ASMstmtnb, CInt64_GetULong(&num)); - return GetHashNameNodeExport(buf); -} - -static void ScanOptionalLabel(void) { - if (tk == TK_INTCONST) { - if (lookahead() == ':') { - InlineAsm_DefineLabel(MakeLocalLabel(tkintconst)); - tk = lex(); - tk = lex(); - } - } else { - if (tkidentifier->name[0] == '@') { - InlineAsm_DefineLabel(tkidentifier); - tk = lex(); - if (tk == ':') - tk = lex(); - } else { - HashNameNode *name = tkidentifier; - short t = lookahead(); - tkidentifier = name; - if (t == ':') { - InlineAsm_DefineLabel(name); - tk = lex(); - tk = lex(); - } - } - } -} - -static void ScanStatements(volatile short endToken, AssemblerType mode) { - if (setjmp(InlineAsm_assemblererror)) { - while (tk != TK_EOL && tk != endToken && tk != '}' && tk) - tk = lex(); - if (tk == ';' || tk == TK_EOL) - tk = lex(); - } else { - InlineAsm_Initialize(mode); - InlineAsm_gccmode = 0; - if (setjmp(InlineAsm_assemblererror)) { - while (tk != ';' && tk != TK_EOL && tk != endToken && tk != '}' && tk) - tk = lex(); - if (tk == ';' || tk == TK_EOL) - tk = lex(); - } - - while (tk && tk != endToken) { - backtracking = 0; - sourceoffset = CPrep_GetFileOffsetInfo(&cparser_fileoffset); - if (tk == '"') { - if (InlineAsm_gccmode) { - tk = lex(); - InlineAsm_gcc_parse(); - } else { - InlineAsm_gccmode = 1; - copts.cplusplus = 0; - copts.asmpoundcomment = 1; - tk = lex(); - } - } - - if (tk == '.') { - InlineAsm_ScanAssemblyDirective(); - } else if (tk == TK_IDENTIFIER) { - ScanOptionalLabel(); - if (tk == TK_IDENTIFIER) - InlineAsm_ScanAssemblyInstruction(); - } else if (tk == TK_INTCONST) { - ScanOptionalLabel(); - if (tk == TK_IDENTIFIER) - InlineAsm_ScanAssemblyInstruction(); - } - - if (InlineAsm_gccmode && tk == '"') { - tk = lex(); - InlineAsm_gcc_parse(); - } - - if (tk == ';' || tk == TK_EOL) { - CPrep_TokenStreamFlush(); - tk = lex(); - } else if (tk != endToken) { - if (endToken == ')') - CError_Error(CErrorStr115); - else - CError_Error(CErrorStr113); - } - } - } -} - -void InlineAsm_ScanStatements(volatile short endToken) { - ScanStatements(endToken, AssemblerType_0); -} - -void InlineAsm_ScanFunction(volatile short endToken) { - ScanStatements(endToken, AssemblerType_1); -} - -void InlineAsm_Assemble(void) { - short token = (tk == '(') ? ')' : '}'; - char save_pc = copts.asmpoundcomment; - char save_cpp = copts.cplusplus; - - cprep_nostring = 1; - CFunc_AppendStatement(ST_NOP); - first_ST_ASM = curstmt; - ASMstmtnb++; - - cprep_eoltokens = 1; - in_assembler = 1; - tk = lex(); - InlineAsm_ScanStatements(token); - in_assembler = 0; - cprep_eoltokens = 0; - cprep_nostring = 0; - - copts.asmpoundcomment = save_pc; - copts.cplusplus = save_cpp; -} - -void InlineAsm_PackAsmStatement(Statement *stmt, Statement *first, void **output, SInt32 *outsize) { - InlineAsm *src; - InlineAsm *dest; - IAOperand *op; - SInt32 i; - SInt32 size; - - src = (InlineAsm *) stmt->expr; - size = sizeof(InlineAsm) + sizeof(IAOperand) * src->argcount; - dest = galloc(size); - memcpy(dest, src, size); - - for (i = 0, op = dest->args; i < dest->argcount; i++, op++) { - switch (op->type) { - case IAOpnd_0: - break; - case IAOpnd_Reg: - case IAOpnd_4: - op->u.reg.object = (Object *) CInline_GetLocalID(op->u.reg.object); - break; - case IAOpnd_Lab: - op->u.lab.label = (CLabel *) CInline_GetStatementNumber(first, op->u.lab.label->stmt); - break; - case IAOpnd_LabDiff: - op->u.labdiff.label1 = (CLabel *) CInline_GetStatementNumber(first, op->u.labdiff.label1->stmt); - op->u.labdiff.label2 = (CLabel *) CInline_GetStatementNumber(first, op->u.labdiff.label2->stmt); - break; - } - } - - *output = dest; - *outsize = size; -} - -void InlineAsm_UnpackAsmStatement(Statement *stmt, CLabel **labelArray, Boolean flag, void *data, SInt32 size) { - InlineAsm *ia; - IAOperand *op; - SInt32 i; - - ia = galloc(size); - memcpy(ia, data, size); - - for (i = 0, op = ia->args; i < ia->argcount; i++, op++) { - switch (op->type) { - case IAOpnd_0: - break; - case IAOpnd_Reg: - case IAOpnd_4: - op->u.reg.object = CInline_GetLocalObj((SInt32) op->u.reg.object, flag); - break; - case IAOpnd_Lab: - op->u.lab.label = labelArray[(SInt16) op->u.lab.label]; - break; - case IAOpnd_LabDiff: - op->u.labdiff.label1 = labelArray[(SInt16) op->u.labdiff.label1]; - op->u.labdiff.label2 = labelArray[(SInt16) op->u.labdiff.label2]; - break; - } - } - - stmt->expr = (ENode *) ia; -} - -void InlineAsm_CheckLocalUsage(Statement *stmt) { - InlineAsm *ia = (InlineAsm *) stmt->expr; - IAOperand *op; - SInt32 i; - - for (i = 0, op = ia->args; i < ia->argcount; i++, op++) { - switch (op->type) { - case IAOpnd_Reg: - if (op->u.reg.object) - SetVarUsage(op->u.reg.object, 0); - break; - case IAOpnd_4: - SetVarUsage(op->u.obj.obj, 1); - break; - } - } -} - -CLabel *InlineAsm_GetReferencedLabel(Statement *stmt) { - InlineAsm *ia = (InlineAsm *) stmt->expr; - IAOperand *op; - SInt32 i; - - for (i = 0, op = ia->args; i < ia->argcount; i++, op++) { - if (op->type == IAOpnd_Lab) - return op->u.lab.label; - if (op->type == IAOpnd_LabDiff) - return op->u.labdiff.label1; - } - - return NULL; -} - -CLabel *InlineAsm_GetReferencedLabel2(Statement *stmt) { - InlineAsm *ia = (InlineAsm *) stmt->expr; - IAOperand *op; - SInt32 i; - - for (i = 0, op = ia->args; i < ia->argcount; i++, op++) { - if (op->type == IAOpnd_LabDiff) - return op->u.labdiff.label2; - } - - return NULL; -} - -Object *InlineAsm_GetObjectOffset(InlineAsm *ia, SInt32 index, SInt32 *offset) { - IAOperand *op; - SInt32 i; - SInt32 counter; - - for (i = 0, counter = 0, op = ia->args; i < ia->argcount; i++, op++) { - if (op->type == IAOpnd_3) { - if (counter++ == index) { - *offset = ((intptr_t) &op->u.obj.obj) - ((intptr_t) ia); - return op->u.obj.obj; - } - } - } - - return NULL; -} - -char *InlineAsm_DumpStatement(Statement *stmt) { - static char buffer[1024]; - InlineAsm *ia; - IAOperand *arg; - int i; - char ch; - SInt32 offset; - - ia = (InlineAsm *) stmt->expr; - - strcpy(buffer, "\""); - strcat(buffer, InlineAsm_GetMnemonic(ia)); - strcat(buffer, "\""); - - for (i = 0, arg = ia->args; i < ia->argcount; i++, arg++) { - char argbuf[1024]; - - switch (arg->type) { - case IAOpnd_Imm: - sprintf(argbuf, " imm(%ld)", arg->u.imm.value); - break; - case IAOpnd_Reg: - ch = ' '; - if (arg->u.reg.effect & EffectWrite) { - if (arg->u.reg.effect & EffectRead) - ch = '+'; - else - ch = '='; - } else { - if (!(arg->u.reg.effect & EffectRead)) - ch = '0'; - } - - if (arg->u.reg.object) { - sprintf(argbuf, - "%creg(%s)", - ch, - arg->u.reg.object->name->name); - } else { - sprintf(argbuf, - "%creg(%s%d)", - ch, - register_class_name[arg->u.reg.rclass], - arg->u.reg.num); - } - break; - - case IAOpnd_3: - case IAOpnd_4: - if (arg->u.obj.offset > 0) - sprintf(argbuf, " obj(%s+%ld)", arg->u.obj.obj->name->name, arg->u.obj.offset); - else if (arg->u.obj.offset < 0) - sprintf(argbuf, " obj(%s-%ld)", arg->u.obj.obj->name->name, -arg->u.obj.offset); - else - sprintf(argbuf, " obj(%s)", arg->u.obj.obj->name->name); - break; - - case IAOpnd_Lab: - sprintf(argbuf, " lab(%s)", arg->u.lab.label->uniquename->name); - break; - - case IAOpnd_LabDiff: - offset = !arg->negated ? 0 : arg->u.labdiff.offset; - sprintf(argbuf, - " labdiff(%s-%s%c%d)", - arg->u.labdiff.label1->uniquename->name, - arg->u.labdiff.label2->uniquename->name, - (arg->negated == 1) ? '-' : '+', - offset - ); - break; - } - - strcat(buffer, argbuf); - } - - return buffer; -} |