1 /* reg.h - registers for bcc */
2 
3 /* Copyright (C) 1992 Bruce Evans */
4 
5 /*
6   The compiler generates "addresses" of the form
7       indirect(indcount) (rx + offset)
8   where
9       rx is a machine register (possibly null)
10       n is the indirection count (possibly 0)
11       offset is a constant.
12   It does not support more complicated formats like
13       indirect(indcount) (rx + index * scale + offset).
14 
15       The register is coded as bit flag in the  storage  component of
16   the symbol structure. This allows groups of registers to be tested
17   using bitwise "&". Throughout the compiler, the group of these bit
18   flags has the type  reg_t. If there are only a few registers, reg_t
19   can be an unsigned char. It must be unsigned if the high bit is
20   used, to avoid sign extension problems. For bootstrapping the compiler
21   from a compiler with no unsigned char, the unsigned type should be
22   used instead (with a signifigant waste of storage).
23 
24       The bit flags should really be defined as ((reg_t) whatever) but
25   then they would not (necessarily) be constant expressions and couldn't
26   be used in switch selectors or (worse) preprocessor expressions.
27 
28       The CONSTANT and GLOBAL (non-) register bits are almost
29   equivalent. A constant with nonzero indirection is marked as a
30   GLOBAL and not a CONSTANT. This makes it easier to test for a constant
31   CONSTANT. Globals which are formed in this way are converted to
32   constants if their indirection count is reset to 0 (by & operator).
33 */
34 
35 /* register bit flags */
36 
37 #define NOSTORAGE 0x000		/* structure/union member offsets */
38 #define CONSTANT  0x001		/* offsets are values */
39 #define BREG      0x002
40 #define DREG      0x004
41 #define INDREG0   0x008
42 #define INDREG1   0x010
43 #define INDREG2   0x020
44 #define LOCAL     0x040
45 #define GLOBAL    0x080		/* offsets from storage name or 0 */
46 #define CCREG     CONSTANT	/* arg to PSHS/PULS functions only */
47 #ifdef I8088
48 # ifdef FRAMEPOINTER
49 #  define FRAMEREG LOCAL
50 # endif
51 # define STACKREG 0x100
52 # define DATREG1  0x200
53 # define DATREG2  0x400
54 # define DATREG1B 0x800
55 #endif
56 #ifdef MC6809
57 # define DPREG    LOCAL		/* arg to PSHS/PULS functions only */
58 # define PCREG    GLOBAL	/* arg to PSHS/PULS functions only */
59 #endif
60 
61 /* data for pushing and pulling registers */
62 
63 #define MINREGCHAR 'A'
64 #ifdef I8088
65 # define FLAGSREGCHAR 'f'
66 # define pushchar() pushlist(AXREG)
67 #endif
68 #ifdef MC6809
69 # define pushchar() pushlist(BREG)
70 #endif
71 
72 /* special registers */
73 
74 #ifdef I8088
75 # define ALREG    BREG
76 # define AXREG    DREG
77 # define DXREG    DATREG2
78 # define MULREG   DATREG1B
79 # define SHIFTREG DATREG1B
80 #endif
81 #ifdef MC6809
82 # define XREG INDREG0		/* XREG is special for ABX in index & switch */
83 # define YREG INDREG2		/* XREG and YREG allow LEA (Z test) in cmp() */
84 #endif
85 
86 /* groups of registers */
87 
88 #define ALLDATREGS (BREG|DREG)
89 #define CHARREGS BREG
90 #define MAXREGS 1		/* number of data registers */
91 #define WORKDATREGS (BREG|DREG)
92 
93 /* function call and return registers */
94 
95 #define ARGREG RETURNREG	/* for (1st) argument */
96 #define LONGARGREGS LONGRETURNREGS	/* for long or float arg */
97 #define LONGRETURNREGS (INDREG0|LONGREG2)
98 #define LONGREG2 DREG
99 #ifdef I8088
100 # define LONGRETSPECIAL	/* LONGRETURNREGS!=RETURNREG && RETURNREG==LONGREG2 */
101 # define RETURNREG DREG
102 #endif
103 #ifdef MC6809
104 # define RETURNREG INDREG0
105 #endif
106 
107 /* registers which can be pulled as a group with the program counter */
108 /* to perform an efficient function return */
109 
110 #ifdef MC6809
111 #define JUNK1REGS BREG		/* 1 bytes locals to discard */
112 #define JUNK2REGS INDREG2
113 #define JUNK3REGS (BREG|INDREG2)
114 #define JUNK4REGS (INDREG1|INDREG2)
115 #endif
116 
117 /* registers which can be pushed as a group with the first argument */
118 /* to perform an efficient function startup */
119 
120 #ifdef MC6809
121 # define LOC1REGS CCREG		/* 1 bytes local to allocate */
122 # define LOC2REGS DREG
123 # define LOC3REGS (CCREG|DREG)
124 # define LOC4REGS (CCREG|DREG|DPREG)
125 # endif
126 
127 /* registers to be used by software operations */
128 
129 #define OPREG INDREG0		/* 2nd reg for software ops (1st is DREG) */
130 #define OPWORKREG INDREG2	/* 3rd register for software ops */
131 
132 /* maximum indirection count for 1 instruction */
133 
134 #ifdef I8088
135 # define MAXINDIRECT 1
136 #endif
137 #ifdef MC6809
138 # define MAXINDIRECT 2
139 #endif
140