summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/InlineAsm.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/InlineAsm.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-main.tar.gz
MWCC-main.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/InlineAsm.c')
-rw-r--r--compiler_and_linker/unsorted/InlineAsm.c680
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;
-}