summaryrefslogtreecommitdiff
path: root/includes/compiler/Operands.h
blob: 8808e603079e0d59d9cc40b06673258cc7e56c5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#ifndef COMPILER_OPERANDS_H
#define COMPILER_OPERANDS_H

#include "compiler/common.h"

#ifdef __MWERKS__
#pragma options align=mac68k
#endif

extern Float one_point_zero;

enum OperandType {
    // Value in a register (identified by 'reg')
    OpndType_GPR = 0,
    // Uses 'reg', 'object, 'immOffset'
    OpndType_GPR_ImmOffset = 1,
    // Uses 'reg', 'regOffset'
    OpndType_GPR_Indexed = 2,
    // Value in two registers (identified by 'reg' and 'regHi')
    OpndType_GPRPair = 3,
    // Immediate 32-bit value
    OpndType_Absolute = 4,
    // Value in a float register (identified by 'reg')
    OpndType_FPR = 5,
    // Value in a vector register (identified by 'reg')
    OpndType_VR = 6,
    // Condition value: 'reg' stores which condition register, and 'regOffset' is equal to ENOTEQU, EEQU, EGREATEREQU,
    // ELESS, ELESS or ELESSEQU
    OpndType_CRField = 7,
    // Value of a symbol (identified by 'object')
    OpndType_Symbol = 8,
    // Reference to a location (at 'reg', offset using 'object' and 'immOffset')
    OpndType_IndirectGPR_ImmOffset = 9,
    // Reference to a location (at 'reg', offset using the value of register 'regOffset')
    OpndType_IndirectGPR_Indexed = 0xA,
    // Reference to a symbol (identified by 'object')
    OpndType_IndirectSymbol = 0xB
};

// These are probably the same as the PCode Flags and can be unified?
enum {
    OpndFlags_Const = 0x40,
    OpndFlags_Volatile = 0x80
};

struct Operand {
    enum OperandType optype;
    SInt16 reg;
    SInt16 regHi;
    SInt16 regOffset;
    SInt32 immOffset;
    SInt32 immediate;
    Object *object;
    UInt32 flags;
};

extern void load_immediate(short reg, SInt32 value);
extern void symbol_operand(Operand *op, Object *obj);
extern void indirect(Operand *op, ENode *expr);
extern void combine(Operand *opA, Operand *opB, short output_reg, Operand *opOut);
extern void coerce_to_addressable(Operand *op);
extern void Coerce_to_register(Operand *op, Type *type, short output_reg);
extern void coerce_to_register_pair(Operand *op, Type *type, short output_reg, short output_regHi);
extern void Coerce_to_fp_register(Operand *op, Type *type, short output_reg);
extern void Coerce_to_v_register(Operand *op, Type *type, short output_reg);
extern void store(short reg, Operand *op, Type *type);
extern void store_pair(short reg, short regHi, Operand *op, Type *type);
extern void store_fp(short reg, Operand *op, Type *tint);
extern void store_v(short reg, Operand *op, Type *tstruct);
extern void extend32(Operand *op, Type *type, short output_reg);
extern void extend64(Operand *op, Type *type, short output_reg, short output_regHi);
extern void load_floating_constant(short reg, Type *type, Float *data);
extern void convert_integer_to_floating(Operand *op, Boolean is_single, short output_reg);
extern void convert_unsigned_to_floating(Operand *op, Boolean is_single, short output_reg);
extern void convert_floating_to_integer(Operand *op, short output_reg);
extern void convert_floating_to_unsigned(Operand *op, short output_reg);
extern void extract_bitfield(Operand *input_op, TypeBitfield *tbitfield, short output_reg, Operand *output_op);
extern void insert_bitfield(short reg, Operand *op, TypeBitfield *tbitfield);
extern void load_address(short dest_reg, Operand *op);

#ifdef __MWERKS__
#pragma options align=reset
#endif

#endif