1 /* load.c: This code "loads" code into the code segments. */
3 /* This file is part of bc written for MINIX.
4 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
6 This program 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 of the License , or
9 (at your option) any later version.
11 This program 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.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 You may contact the author by:
21 e-mail: phil@cs.wwu.edu
22 us-mail: Philip A. Nelson
23 Computer Science Department, 9062
24 Western Washington University
25 Bellingham, WA 98226-9062
27 *************************************************************************/
35 program_counter load_adr
;
39 /* Initialize the load sequence. */
50 /* addbyte adds one BYTE to the current code segment. */
55 int seg
, offset
, func
;
57 /* If there was an error, don't continue. */
58 if (had_error
) return;
60 /* Calculate the segment and offset. */
61 seg
= load_adr
.pc_addr
>> BC_SEG_LOG
;
62 offset
= load_adr
.pc_addr
++ % BC_SEG_SIZE
;
63 func
= load_adr
.pc_func
;
65 if (seg
>= BC_MAX_SEGS
)
67 yyerror ("Function too big.");
71 if (functions
[func
].f_body
[seg
] == NULL
)
72 functions
[func
].f_body
[seg
] = (char *) bc_malloc (BC_SEG_SIZE
);
75 functions
[func
].f_body
[seg
][offset
] = byte
;
76 functions
[func
].f_code_size
++;
80 /* Define a label LAB to be the current program counter. */
87 int group
, offset
, func
;
89 /* Get things ready. */
90 group
= lab
>> BC_LABEL_LOG
;
91 offset
= lab
% BC_LABEL_GROUP
;
92 func
= load_adr
.pc_func
;
94 /* Make sure there is at least one label group. */
95 if (functions
[func
].f_label
== NULL
)
97 functions
[func
].f_label
=
98 (bc_label_group
*) bc_malloc (sizeof(bc_label_group
));
99 functions
[func
].f_label
->l_next
= NULL
;
102 /* Add the label group. */
103 temp
= functions
[func
].f_label
;
106 if (temp
->l_next
== NULL
)
108 temp
->l_next
= (bc_label_group
*) bc_malloc (sizeof(bc_label_group
));
109 temp
->l_next
->l_next
= NULL
;
116 temp
->l_adrs
[offset
] = load_adr
.pc_addr
;
119 /* Several instructions have integers in the code. They
120 are all known to be legal longs. So, no error code
121 is added. STR is the pointer to the load string and
122 must be moved to the last non-digit character. */
135 while (isdigit(**str
))
136 val
= val
*10 + *(*str
)++ - '0';
145 /* load_code loads the CODE into the machine. */
152 long ap_name
; /* auto or parameter name. */
154 long vaf_name
; /* variable, array or function number. */
156 program_counter save_adr
;
164 /* If there was an error, don't continue. */
165 if (had_error
) return;
169 if (*str
== '"') load_str
= FALSE
;
189 addbyte (*str
++ + 10 - 'A');
191 addbyte (*str
++ - '0');
199 case '"': /* Starts a string. */
203 case 'N': /* A label */
205 label_no
= long_val (&str
);
206 def_label (label_no
);
209 case 'B': /* Branch to label. */
210 case 'J': /* Jump to label. */
211 case 'Z': /* Branch Zero to label. */
213 label_no
= long_val (&str
);
214 if (label_no
> 65535L)
215 { /* Better message? */
216 fprintf (stderr
,"Program too big.\n");
219 addbyte ( (char) label_no
& 0xFF);
220 addbyte ( (char) label_no
>> 8);
223 case 'F': /* A function, get the name and initialize it. */
225 func
= long_val (&str
);
228 printf ("Loading function number %d\n", func
);
230 /* get the parameters */
231 while (*str
++ != '.')
238 ap_name
= long_val (&str
);
240 printf ("parameter number %d\n", ap_name
);
242 functions
[(int)func
].f_params
=
243 nextarg (functions
[(int)func
].f_params
, ap_name
);
246 /* get the auto vars */
249 if (*str
== ',') str
++;
250 ap_name
= long_val (&str
);
252 printf ("auto number %d\n", ap_name
);
254 functions
[(int)func
].f_autos
=
255 nextarg (functions
[(int)func
].f_autos
, ap_name
);
258 load_adr
.pc_func
= func
;
259 load_adr
.pc_addr
= 0;
262 case ']': /* A function end */
263 functions
[load_adr
.pc_func
].f_defined
= TRUE
;
267 case 'C': /* Call a function. */
269 func
= long_val (&str
);
271 addbyte ( (char) func
);
274 addbyte ((func
>> 8) & 0xff | 0x80);
275 addbyte (func
& 0xff);
277 if (*str
== ',') str
++;
283 case 'c': /* Call a special function. */
288 case 'K': /* A constant.... may have an "F" in it. */
293 case 'd': /* Decrement. */
294 case 'i': /* Increment. */
295 case 'l': /* Load. */
296 case 's': /* Store. */
297 case 'A': /* Array Increment */
298 case 'M': /* Array Decrement */
299 case 'L': /* Array Load */
300 case 'S': /* Array Store */
302 vaf_name
= long_val (&str
);
307 addbyte ((vaf_name
>> 8) & 0xff | 0x80);
308 addbyte (vaf_name
& 0xff);
312 case '@': /* A command! */
324 case '\n': /* Ignore the newlines */
327 default: /* Anything else */