summaryrefslogtreecommitdiff
path: root/includes/compiler/InstrSelection.h
blob: a3b90b3dd1500ed2988ba3f837bb3ca84e0f4263 (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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#ifndef COMPILER_INSTRSELECTION_H
#define COMPILER_INSTRSELECTION_H

#include "compiler/common.h"
#include "compiler/enode.h"
#include "compiler/Operands.h"
#include "compiler/PCodeInfo.h"

typedef struct PrecomputedOperand {
    struct PrecomputedOperand *next;
    SInt32 precompid;
    Operand operand;
} PrecomputedOperand;

extern PrecomputedOperand *precomputedoperands;
extern void (*cgdispatch[MAXEXPR + 1])(ENode *, short, short, Operand *);

extern void init_cgdispatch(void);
extern void gen_DEFINE(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_REUSE(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_POSTINCDEC(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_INDIRECT(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_MONMIN(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_BINNOT(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_FORCELOAD(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_MUL(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_DIV(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_MODULO(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_ADD(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_SUB(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_SHL(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_SHR(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_AND(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_XOR(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_OR(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_ASS(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern ENode *evaluate_and_skip_comma(ENode *expr);
extern void gen_COMMA(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_TYPCON(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_BITFIELD(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_INTCONST(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_FLOATCONST(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_STRINGCONST(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_COND(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_CONDASS(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_FUNCCALL(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_OBJREF(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_UNEXPECTED(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void binary_operator(Opcode opcode, ENode *left, ENode *right, short outputReg, Operand *output);
extern void unary_operator(Opcode opcode, ENode *expr, short outputReg, Operand *output);
extern void fp_unary_operator(Opcode opcode, ENode *expr, short outputReg, Operand *output);
extern void fp_multiply_add(Opcode opcode, ENode *a, ENode *b, ENode *c, short outputReg, Operand *output);
extern void gen_COMPARE(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_LOGICAL(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_NULLCHECK(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_PRECOMP(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void logical_expression(ENode *cond, PCodeLabel *a, PCodeLabel *b, PCodeLabel *c);
extern void gen_condition(ENode *cond, Operand *output);
extern void gen_condition_gpr(ENode *cond, Operand *output, short outputReg);
extern void gen_negated_condition_gpr(ENode *cond, Operand *output, short outputReg);
extern void compare_floating(short nt, ENode *left, ENode *right, Operand *output);
extern void compare_integer(short nt, ENode *left, ENode *right, Operand *output);
extern void compare_immediate(short nt, ENode *left, SInt32 value, Operand *output);
extern void compare_immediate_long(short nt, ENode *left, SInt32 value, Operand *output);
extern int ismaskconstant(SInt32 value, short *first, short *last);
extern int ispostincrementopportunity(ENode *expr, Operand *op, SInt32 *value);
extern void add_register_immediate(short regA, short regB, SInt32 value);
extern void I8_gen_ADD(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_INTCONST(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_SUB(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_XOR(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_OR(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_AND(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern int I8_getbit(UInt64 val);
extern int I8_log2n(UInt64 val);
extern void I8_ShiftLeftImmediate(Operand opnd, SInt32 value, int is_unsigned, SInt32 size, short reg, short regHi);
extern void I8_ShiftRightImmediate(Operand opnd, SInt32 value, int is_unsigned, short reg, short regHi, int unk);
extern void I8_gen_MUL(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_BINNOT(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_MONMIN(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_ASS(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_POSTINCDEC(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_INDIRECT(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_condition(ENode *cond, Operand *output, int write_to_gpr);
extern void I8_gen_SHL_SHR(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_DIV_MOD(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void I8_gen_TYPCON(ENode *expr, short outputReg, short outputRegHi, Operand *output);
extern void gen_VECTOR128CONST(ENode *expr, short outputReg, short outputRegHi, Operand *output);

#define GEN_NODE(node, opnd) cgdispatch[(node)->type]((node), 0, 0, (opnd))
#define GEN_NODE_TO_REG(node, reg, regHi, opnd) cgdispatch[(node)->type]((node), (reg), (regHi), (opnd))

#define ENSURE_GPR(opnd, type, reg) \
do {                                \
  if ((opnd)->optype != OpndType_GPR) \
   Coerce_to_register((opnd), (type), (reg)); \
} while (0)
#define ENSURE_FPR(opnd, type, reg) \
do {                                \
  if ((opnd)->optype != OpndType_FPR) \
   Coerce_to_fp_register((opnd), (type), (reg)); \
} while (0)
#define ENSURE_VR(opnd, type, reg) \
do {                                \
  if ((opnd)->optype != OpndType_VR) \
   Coerce_to_v_register((opnd), (type), (reg)); \
} while (0)

#define GEN_NODE_TO_GPR(node, opnd, type, reg) \
do {                                           \
  GEN_NODE((node), (opnd));                    \
  ENSURE_GPR((opnd), (type), (reg));           \
} while (0)

#define GEN_NODE_TO_FPR(node, opnd, type, reg) \
do {                                           \
  GEN_NODE((node), (opnd));                    \
  ENSURE_FPR((opnd), (type), (reg));           \
} while (0)

#define GEN_NODE_TO_VR(node, opnd, type, reg) \
do {                                           \
  GEN_NODE((node), (opnd));                    \
  ENSURE_VR((opnd), (type), (reg));           \
} while (0)


#endif