mirror of https://git.wuffs.org/MWCC
246 lines
5.4 KiB
C
246 lines
5.4 KiB
C
#ifndef COMPILER_INLINEASM_H
|
|
#define COMPILER_INLINEASM_H
|
|
|
|
#include "compiler/common.h"
|
|
#include "compiler/PCodeInfo.h"
|
|
|
|
#ifdef __MWERKS__
|
|
#pragma options align=mac68k
|
|
#endif
|
|
typedef struct IAMnemonic {
|
|
char *name;
|
|
UInt32 x4;
|
|
char *format;
|
|
UInt32 cpu;
|
|
UInt32 x10;
|
|
} IAMnemonic;
|
|
|
|
typedef struct IARegister {
|
|
char *name;
|
|
RegClass rclass;
|
|
SInt32 num;
|
|
Object *object;
|
|
} IARegister;
|
|
|
|
typedef enum IAOperandType {
|
|
IAOpnd_0,
|
|
IAOpnd_Imm,
|
|
IAOpnd_Reg,
|
|
IAOpnd_3,
|
|
IAOpnd_4,
|
|
IAOpnd_Lab,
|
|
IAOpnd_6,
|
|
IAOpnd_7,
|
|
IAOpnd_LabDiff
|
|
} IAOperandType;
|
|
typedef struct IAOperand {
|
|
IAOperandType type;
|
|
Boolean negated;
|
|
union {
|
|
// type 1
|
|
struct {
|
|
SInt32 value;
|
|
} imm;
|
|
// type 2
|
|
struct {
|
|
SInt32 num;
|
|
Object *object;
|
|
short effect;
|
|
short rclass;
|
|
} reg;
|
|
// type 3, 4
|
|
struct {
|
|
SInt32 offset;
|
|
Object *obj;
|
|
short unk;
|
|
} obj;
|
|
// type 5
|
|
struct {
|
|
CLabel *label;
|
|
} lab;
|
|
// type 6
|
|
struct {
|
|
SInt32 num;
|
|
UInt8 unk4;
|
|
short effect;
|
|
short rclass;
|
|
} unk6;
|
|
// type 7
|
|
struct {
|
|
SInt32 value;
|
|
Boolean unk1;
|
|
short unk2;
|
|
short unk3;
|
|
} unk7;
|
|
// type 8
|
|
struct {
|
|
CLabel *label1;
|
|
CLabel *label2;
|
|
SInt32 offset;
|
|
} labdiff;
|
|
} u;
|
|
} IAOperand;
|
|
|
|
typedef enum IAExprType {
|
|
IAExpr_0,
|
|
IAExpr_1,
|
|
IAExpr_2,
|
|
IAExpr_3,
|
|
IAExpr_4,
|
|
IAExpr_5,
|
|
IAExpr_6,
|
|
IAExpr_7,
|
|
IAExpr_8,
|
|
IAExpr_9,
|
|
IAExpr_10
|
|
} IAExprType;
|
|
|
|
typedef struct IAExpr {
|
|
IAExprType type;
|
|
UInt8 flags;
|
|
short reg;
|
|
SInt32 value;
|
|
Object *object;
|
|
Object *xC;
|
|
Object *x10;
|
|
CLabel *label;
|
|
CLabel *x18;
|
|
} IAExpr;
|
|
|
|
enum {
|
|
IAFlag1 = 1,
|
|
IAFlag2 = 2
|
|
};
|
|
enum {
|
|
IAFlagsB_1 = 1,
|
|
IAFlagsB_2 = 2,
|
|
IAFlagsB_4 = 4,
|
|
IAFlagsB_8 = 8,
|
|
IAFlagsB_10 = 0x10,
|
|
IAFlagsB_20 = 0x20,
|
|
IAFlagsB_40 = 0x40
|
|
};
|
|
|
|
typedef struct InlineAsm {
|
|
Opcode opcode;
|
|
unsigned char flags;
|
|
unsigned char flags2;
|
|
short argcount;
|
|
IAOperand args[0];
|
|
} InlineAsm;
|
|
|
|
typedef struct IALookupResult {
|
|
HashNameNode *name;
|
|
CLabel *label;
|
|
Object *object;
|
|
Type *type;
|
|
UInt32 value;
|
|
Boolean has_value;
|
|
} IALookupResult;
|
|
|
|
typedef struct IAEntryPoint {
|
|
short x0;
|
|
char x2;
|
|
int x4;
|
|
Object *x8;
|
|
SInt32 size;
|
|
} IAEntryPoint;
|
|
|
|
typedef enum IAEffectType {
|
|
IAEffect_0,
|
|
IAEffect_1,
|
|
IAEffect_2,
|
|
IAEffect_3,
|
|
IAEffect_4
|
|
} IAEffectType;
|
|
typedef struct IAEffect {
|
|
IAEffectType type;
|
|
Object *object;
|
|
SInt32 offset;
|
|
SInt32 size;
|
|
} IAEffect;
|
|
|
|
enum {
|
|
IAMaxOperands = 16,
|
|
IAMaxLabels = 16
|
|
};
|
|
|
|
typedef struct IAEffects {
|
|
Boolean x0;
|
|
Boolean x1;
|
|
Boolean x2;
|
|
Boolean x3;
|
|
Boolean x4;
|
|
Boolean x5;
|
|
SInt32 numoperands;
|
|
SInt32 numlabels;
|
|
IAEffect operands[IAMaxOperands];
|
|
CLabel *labels[IAMaxLabels];
|
|
} IAEffects;
|
|
|
|
#ifdef __MWERKS__
|
|
#pragma options align=reset
|
|
#endif
|
|
|
|
extern int backtracking;
|
|
extern jmp_buf backtrack;
|
|
extern jmp_buf InlineAsm_assemblererror;
|
|
|
|
extern int allow_array_expressions;
|
|
|
|
extern void AssemblerError(void);
|
|
extern void InlineAsm_SyntaxError(short code);
|
|
extern CLabel *InlineAsm_LookupLabel(HashNameNode *name);
|
|
extern CLabel *InlineAsm_DeclareLabel(HashNameNode *name);
|
|
extern Boolean InlineAsm_LookupSymbolOrTag(HashNameNode *name, IALookupResult *result, Boolean allow_tag);
|
|
extern Boolean InlineAsm_LookupSymbol(HashNameNode *name, IALookupResult *result);
|
|
extern SInt32 InlineAsm_StructMemberOffset(Type *type);
|
|
extern SInt32 InlineAsm_StructArrayMemberOffset(Type *type);
|
|
extern SInt32 InlineAsm_StructPointerMemberOffset(Type *type);
|
|
extern SInt32 InlineAsm_ConstantExpression(void);
|
|
extern HashNameNode *MakeLocalLabel(CInt64 num);
|
|
extern void InlineAsm_ScanStatements(volatile short endToken);
|
|
extern void InlineAsm_ScanFunction(volatile short endToken);
|
|
extern void InlineAsm_Assemble(void);
|
|
extern void InlineAsm_PackAsmStatement(Statement *stmt, Statement *first, void **output, SInt32 *outsize);
|
|
extern void InlineAsm_UnpackAsmStatement(Statement *stmt, CLabel **labelArray, Boolean flag, void *data, SInt32 size);
|
|
extern void InlineAsm_CheckLocalUsage(Statement *stmt);
|
|
extern CLabel *InlineAsm_GetReferencedLabel(Statement *stmt);
|
|
extern CLabel *InlineAsm_GetReferencedLabel2(Statement *stmt);
|
|
extern Object *InlineAsm_GetObjectOffset(InlineAsm *ia, SInt32 index, SInt32 *offset);
|
|
extern char *InlineAsm_DumpStatement(Statement *stmt);
|
|
|
|
// unknown name
|
|
CW_INLINE void InlineAsm_InitExpr5(IAExpr *expr, SInt32 value) {
|
|
expr->type = IAExpr_5;
|
|
expr->flags = 0;
|
|
expr->value = value;
|
|
expr->reg = 0;
|
|
expr->object = NULL;
|
|
expr->xC = NULL;
|
|
expr->x10 = NULL;
|
|
expr->label = NULL;
|
|
expr->x18 = NULL;
|
|
}
|
|
|
|
// unknown name
|
|
CW_INLINE int InlineAsm_CheckExpr(IAExpr *expr) {
|
|
return (expr->xC == NULL && expr->object == NULL && expr->label == NULL);
|
|
}
|
|
|
|
// unknown name
|
|
CW_INLINE SInt32 InlineAsm_GetExprValue(IAExpr *expr) {
|
|
switch (expr->type) {
|
|
case IAExpr_8:
|
|
return HIGH_PART(expr->value);
|
|
case IAExpr_7:
|
|
return (short) (expr->value >> 16);
|
|
case IAExpr_6:
|
|
return (short) expr->value;
|
|
default:
|
|
return expr->value;
|
|
}
|
|
}
|
|
|
|
#endif
|