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
|