blob: 822bda7b3d3da4d0162cea4717eba0f7855a06c8 (
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
129
130
131
132
133
134
135
136
137
138
139
|
/* reg.h - registers for bcc */
/* Copyright (C) 1992 Bruce Evans */
/*
The compiler generates "addresses" of the form
indirect(indcount) (rx + offset)
where
rx is a machine register (possibly null)
n is the indirection count (possibly 0)
offset is a constant.
It does not support more complicated formats like
indirect(indcount) (rx + index * scale + offset).
The register is coded as bit flag in the storage component of
the symbol structure. This allows groups of registers to be tested
using bitwise "&". Throughout the compiler, the group of these bit
flags has the type reg_t. If there are only a few registers, reg_t
can be an unsigned char. It must be unsigned if the high bit is
used, to avoid sign extension problems. For bootstrapping the compiler
from a compiler with no unsigned char, the unsigned type should be
used instead (with a signifigant waste of storage).
The bit flags should really be defined as ((reg_t) whatever) but
then they would not (necessarily) be constant expressions and couldn't
be used in switch selectors or (worse) preprocessor expressions.
The CONSTANT and GLOBAL (non-) register bits are almost
equivalent. A constant with nonzero indirection is marked as a
GLOBAL and not a CONSTANT. This makes it easier to test for a constant
CONSTANT. Globals which are formed in this way are converted to
constants if their indirection count is reset to 0 (by & operator).
*/
/* register bit flags */
#define NOSTORAGE 0x000 /* structure/union member offsets */
#define CONSTANT 0x001 /* offsets are values */
#define BREG 0x002
#define DREG 0x004
#define INDREG0 0x008
#define INDREG1 0x010
#define INDREG2 0x020
#define LOCAL 0x040
#define GLOBAL 0x080 /* offsets from storage name or 0 */
#define CCREG CONSTANT /* arg to PSHS/PULS functions only */
#ifdef I8088
# ifdef FRAMEPOINTER
# define FRAMEREG LOCAL
# endif
# define STACKREG 0x100
# define DATREG1 0x200
# define DATREG2 0x400
# define DATREG1B 0x800
#endif
#ifdef MC6809
# define DPREG LOCAL /* arg to PSHS/PULS functions only */
# define PCREG GLOBAL /* arg to PSHS/PULS functions only */
#endif
/* data for pushing and pulling registers */
#define MINREGCHAR 'A'
#ifdef I8088
# define FLAGSREGCHAR 'f'
# define pushchar() pushlist(AXREG)
#endif
#ifdef MC6809
# define pushchar() pushlist(BREG)
#endif
/* special registers */
#ifdef I8088
# define ALREG BREG
# define AXREG DREG
# define DXREG DATREG2
# define MULREG DATREG1B
# define SHIFTREG DATREG1B
#endif
#ifdef MC6809
# define XREG INDREG0 /* XREG is special for ABX in index & switch */
# define YREG INDREG2 /* XREG and YREG allow LEA (Z test) in cmp() */
#endif
/* groups of registers */
#define ALLDATREGS (BREG|DREG)
#define CHARREGS BREG
#define MAXREGS 1 /* number of data registers */
#define WORKDATREGS (BREG|DREG)
/* function call and return registers */
#define ARGREG RETURNREG /* for (1st) argument */
#define LONGARGREGS LONGRETURNREGS /* for long or float arg */
#define LONGRETURNREGS (INDREG0|LONGREG2)
#define LONGREG2 DREG
#ifdef I8088
# define LONGRETSPECIAL /* LONGRETURNREGS!=RETURNREG && RETURNREG==LONGREG2 */
# define RETURNREG DREG
#endif
#ifdef MC6809
# define RETURNREG INDREG0
#endif
/* registers which can be pulled as a group with the program counter */
/* to perform an efficient function return */
#ifdef MC6809
#define JUNK1REGS BREG /* 1 bytes locals to discard */
#define JUNK2REGS INDREG2
#define JUNK3REGS (BREG|INDREG2)
#define JUNK4REGS (INDREG1|INDREG2)
#endif
/* registers which can be pushed as a group with the first argument */
/* to perform an efficient function startup */
#ifdef MC6809
# define LOC1REGS CCREG /* 1 bytes local to allocate */
# define LOC2REGS DREG
# define LOC3REGS (CCREG|DREG)
# define LOC4REGS (CCREG|DREG|DPREG)
# endif
/* registers to be used by software operations */
#define OPREG INDREG0 /* 2nd reg for software ops (1st is DREG) */
#define OPWORKREG INDREG2 /* 3rd register for software ops */
/* maximum indirection count for 1 instruction */
#ifdef I8088
# define MAXINDIRECT 1
#endif
#ifdef MC6809
# define MAXINDIRECT 2
#endif
|