]>
Commit | Line | Data |
---|---|---|
86d7f2db | 1 | /* Definitions for Bytecode Interpreter. |
d62d64da | 2 | Copyright (C) 1993, 1994 Free Software Foundation, Inc. |
86d7f2db JB |
3 | |
4 | This file is part of GNU CC. | |
5 | ||
6 | GNU CC is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2, or (at your option) | |
9 | any later version. | |
10 | ||
11 | GNU CC is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GNU CC; see the file COPYING. If not, write to | |
940d9d63 RK |
18 | the Free Software Foundation, 59 Temple Place - Suite 330, |
19 | Boston, MA 02111-1307, USA. */ | |
86d7f2db | 20 | |
86d7f2db JB |
21 | #define MAXLITERALS 5 |
22 | ||
23 | struct arityvec | |
24 | { | |
25 | char ninputs; | |
26 | char noutputs; | |
27 | char nliterals; | |
28 | char literals[MAXLITERALS]; | |
29 | }; | |
30 | ||
31 | struct argtype | |
32 | { | |
33 | int modealign; /* Argument mode:alignment */ | |
34 | int size; /* Argument size, in bytes */ | |
35 | }; | |
36 | ||
37 | struct callinfo | |
38 | { | |
39 | int nargs; /* Number of arguments in call */ | |
40 | struct argtype retvaltype; /* Type of return value */ | |
41 | struct argtype argtypes[1]; /* Argument types */ | |
42 | }; | |
43 | ||
44 | /* Structure describing a bytecode function. If this changes, we also | |
45 | need to change expand_function_end () in bc-trans.c */ | |
46 | struct bytecode | |
47 | { | |
48 | int stacksize; /* Depth required of evaluation stack. */ | |
49 | int localsize; /* Size in bytes of local variables. */ | |
50 | unsigned char *pc0; /* Initial program counter. */ | |
51 | void **ptrlit; /* Vector of (relocatable) pointer literals. */ | |
52 | struct callinfo *callinfo; /* Vector of procedure call type info. */ | |
53 | }; | |
54 | ||
55 | ||
56 | #define INTERP_BPC 8 /* Bits per char */ | |
57 | #define INTERP_BPI \ | |
58 | (sizeof (int) * INTERP_BPC) /* Bits per int */ | |
59 | ||
60 | ||
61 | #ifndef min | |
62 | #define min(L, R) ((L) < (R) ? (L) : (R)) | |
63 | #endif | |
64 | ||
65 | ||
66 | /* bit field operations. */ | |
67 | ||
68 | /* Low (high) mask: int with low (high) N bits set */ | |
69 | ||
70 | #define LM(N) ((1 << (N)) - 1) | |
71 | #define HM(N) ((~LM (INTERP_BPI - (N)))) | |
72 | ||
73 | ||
74 | /* Sign-extend SIZE low bits of VALUE to integer (typeof VALUE) | |
75 | Signed bitfields are loaded from memory by the sxloadBI instruction, | |
76 | which first retrieves the bitfield with XFIELD and then sign extends | |
77 | it to an SItype. */ | |
78 | ||
79 | #define EXTEND(SIZE, VALUE) \ | |
80 | ({ SUtype value = (SUtype) (VALUE); \ | |
81 | (value & (1 << ((SIZE) - 1)) ? value | ~LM (SIZE) : value); }) | |
82 | ||
83 | ||
84 | /* Given OFFSET:SIZE for a bitfield, calculate: | |
85 | ||
86 | [1] BYTE_OFFSET = the byte offset of the bit field. | |
87 | [2] BIT_OFFSET = the bit offset of the bit field (less than INTERP_BPC). | |
88 | [3] NBYTES = the number of integral bytes in the bit field. | |
89 | [4] TRAILING_BITS= the number of trailing bits (less than INTERP_BPC). | |
90 | ||
91 | ||
92 | , , , , , (memory bytes) | |
93 | ---------------- (bitfield) | |
94 | | | || | | (divisions) | |
95 | ^ ^ ^ ^ | |
96 | | | | |__ [4] (bits) | |
97 | | | |_________ [3] (bytes) | |
98 | | |_________________ [2] (bits) | |
99 | |___________________________ [1] (bytes) | |
100 | ||
101 | ||
102 | The above applies to BYTE_LOW_ENDIAN machines. In BYTE_BIG_ENDIAN machines, the | |
103 | bit numbering is reversed (i.e. bit 0 is the sign bit). | |
104 | ||
ddd5a7c1 | 105 | (All right, so I drew this to keep my tongue in cheek while writing the code below, |
86d7f2db JB |
106 | not because I'm into ASCII art.) */ |
107 | ||
108 | ||
4332e9e4 | 109 | #define BI_PARAMS(OFFSET, SIZE, BYTE_OFFSET, BIT_OFFSET, NBYTES, TRAILING_BITS) \ |
86d7f2db JB |
110 | { BYTE_OFFSET = (OFFSET) / (INTERP_BPC); \ |
111 | BIT_OFFSET = (OFFSET) % (INTERP_BPC); \ | |
112 | NBYTES = ((SIZE) - (INTERP_BPC - (BIT_OFFSET))) / INTERP_BPC; \ | |
113 | if ((NBYTES) < 0 || ((NBYTES) > 64)) \ | |
114 | NBYTES = 0; \ | |
115 | if ((SIZE) + (BIT_OFFSET) <= INTERP_BPC) \ | |
116 | TRAILING_BITS = 0; \ | |
117 | else \ | |
118 | TRAILING_BITS = ((SIZE) - (INTERP_BPC - (BIT_OFFSET))) % INTERP_BPC; } | |
119 | ||
120 | ||
121 | /* SHIFT_IN_BITS retrieves NBITS bits from SOURCE and shifts into | |
122 | DEST. The bit field starts OFFSET bits into SOURCE. | |
123 | ||
124 | OR_IN_BITS copies the NBITS low bits from VALUE into a the bitfield in | |
125 | DEST offset by OFFSET bits. */ | |
126 | ||
127 | ||
86d7f2db JB |
128 | #define SHIFT_IN_BITS(DEST, SOURCE, OFFSET, NBITS) \ |
129 | (DEST = ((DEST) << (NBITS)) \ | |
130 | | (LM ((NBITS)) \ | |
f76b9db2 ILT |
131 | & ((SOURCE) \ |
132 | >> (BYTES_BIG_ENDIAN \ | |
133 | ? (INTERP_BPC - (OFFSET) - (NBITS)) \ | |
134 | : (OFFSET))))) | |
86d7f2db JB |
135 | |
136 | #define OR_IN_BITS(DEST, VALUE, OFFSET, NBITS) \ | |
f76b9db2 ILT |
137 | (DEST = ((DEST) & ~(LM ((NBITS)) \ |
138 | << (BIG_ENDIAN \ | |
139 | ? (INTERP_BPC - (OFFSET) - (NBITS)) \ | |
140 | : (OFFSET))) \ | |
141 | | (((VALUE) & LM ((NBITS))) \ | |
142 | << (BIG_ENDIAN \ | |
143 | ? (INTERP_BPC - (OFFSET) - (NBITS)) \ | |
144 | : (OFFSET))))) | |
86d7f2db JB |
145 | |
146 | /* Procedure call; arguments are a pointer to the function to be called, | |
147 | a pointer to a place to store the return value, a pointer to a vector | |
148 | describing the type of procedure call, and the interpreter's stack pointer, | |
149 | which will point to the first of the arguments at this point. */ | |
150 | ||
151 | #define CALL(FUNC, CALLDESC, RETVAL, SP) __call(FUNC, CALLDESC, RETVAL, SP) | |
152 | ||
153 | ||
154 | /* Procedure return; arguments are a pointer to the calldesc for this | |
155 | function, and a pointer to the place where the value to be returned | |
156 | may be found. Generally the MACHARGS above contain a machine dependent | |
157 | cookie that is used to determine where to jump to. */ | |
158 | ||
159 | #define PROCRET(CALLDESC, RETVAL) return |