1 /*
2 	value.c
3 
4 	value handling
5 
6 	Copyright (C) 2002 Bill Currie <bill@taniwha.org>
7 
8 	Author: Bill Currie <bill@taniwha.org>
9 	Date: 2002/06/04
10 
11 	This program is free software; you can redistribute it and/or
12 	modify it under the terms of the GNU General Public License
13 	as published by the Free Software Foundation; either version 2
14 	of the License, or (at your option) any later version.
15 
16 	This program is distributed in the hope that it will be useful,
17 	but WITHOUT ANY WARRANTY; without even the implied warranty of
18 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 
20 	See the GNU General Public License for more details.
21 
22 	You should have received a copy of the GNU General Public License
23 	along with this program; if not, write to:
24 
25 		Free Software Foundation, Inc.
26 		59 Temple Place - Suite 330
27 		Boston, MA  02111-1307, USA
28 
29 */
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33 
34 #ifdef HAVE_STRING_H
35 # include <string.h>
36 #endif
37 #ifdef HAVE_STRINGS_H
38 # include <strings.h>
39 #endif
40 #include <stdlib.h>
41 
42 #include "QF/alloc.h"
43 #include "QF/dstring.h"
44 #include "QF/hash.h"
45 #include "QF/mathlib.h"
46 #include "QF/va.h"
47 
48 #include "qfcc.h"
49 #include "def.h"
50 #include "defspace.h"
51 #include "diagnostic.h"
52 #include "emit.h"
53 #include "expr.h"
54 #include "reloc.h"
55 #include "strpool.h"
56 #include "symtab.h"
57 #include "type.h"
58 #include "value.h"
59 
60 typedef struct {
61 	def_t      *def;
62 	union {
63 		string_t    string_val;
64 		float       float_val;
65 		float       vector_val[3];
66 		int         entity_val;
67 		int         field_val;
68 		int         func_val;
69 		ex_pointer_t pointer;
70 		float       quaternion_val[4];
71 		int         integer_val;
72 	} i;
73 } immediate_t;
74 
75 static hashtab_t *value_table;
76 static ex_value_t *free_values;
77 
78 static uintptr_t
value_get_hash(const void * _val,void * unused)79 value_get_hash (const void *_val, void *unused)
80 {
81 	const ex_value_t *val = (const ex_value_t *) _val;
82 	return Hash_Buffer (&val->v, sizeof (val->v)) + val->type;
83 }
84 
85 static int
value_compare(const void * _val1,const void * _val2,void * unused)86 value_compare (const void *_val1, const void *_val2, void *unused)
87 {
88 	const ex_value_t *val1 = (const ex_value_t *) _val1;
89 	const ex_value_t *val2 = (const ex_value_t *) _val2;
90 	if (val1->type != val2->type)
91 		return 0;
92 	return memcmp (&val1->v, &val2->v, sizeof (val1->v)) == 0;
93 }
94 
95 static ex_value_t *
new_value(void)96 new_value (void)
97 {
98 	ex_value_t *value;
99 	ALLOC (256, ex_value_t, values, value);
100 	return value;
101 }
102 
103 static ex_value_t *
find_value(const ex_value_t * val)104 find_value (const ex_value_t *val)
105 {
106 	ex_value_t *value;
107 
108 	value = Hash_FindElement (value_table, val);
109 	if (value)
110 		return value;
111 	value = new_value ();
112 	*value = *val;
113 	Hash_AddElement (value_table, value);
114 	return value;
115 }
116 
117 ex_value_t *
new_string_val(const char * string_val)118 new_string_val (const char *string_val)
119 {
120 	ex_value_t  val;
121 	memset (&val, 0, sizeof (val));
122 	val.type = ev_string;
123 	if (string_val)
124 		val.v.string_val = save_string (string_val);
125 	return find_value (&val);
126 }
127 
128 ex_value_t *
new_float_val(float float_val)129 new_float_val (float float_val)
130 {
131 	ex_value_t  val;
132 	memset (&val, 0, sizeof (val));
133 	val.type = ev_float;
134 	val.v.float_val = float_val;
135 	return find_value (&val);
136 }
137 
138 ex_value_t *
new_vector_val(const float * vector_val)139 new_vector_val (const float *vector_val)
140 {
141 	ex_value_t  val;
142 	memset (&val, 0, sizeof (val));
143 	val.type = ev_vector;
144 	VectorCopy (vector_val, val.v.vector_val);
145 	return find_value (&val);
146 }
147 
148 ex_value_t *
new_entity_val(int entity_val)149 new_entity_val (int entity_val)
150 {
151 	ex_value_t  val;
152 	memset (&val, 0, sizeof (val));
153 	val.type = ev_entity;
154 	val.v.entity_val = entity_val;
155 	return find_value (&val);
156 }
157 
158 ex_value_t *
new_field_val(int field_val,type_t * type,def_t * def)159 new_field_val (int field_val, type_t *type, def_t *def)
160 {
161 	ex_value_t  val;
162 	memset (&val, 0, sizeof (val));
163 	val.type = ev_field;
164 	val.v.pointer.val = field_val;
165 	val.v.pointer.type = type;
166 	val.v.pointer.def = def;
167 	return find_value (&val);
168 }
169 
170 ex_value_t *
new_func_val(int func_val,type_t * type)171 new_func_val (int func_val, type_t *type)
172 {
173 	ex_value_t  val;
174 	memset (&val, 0, sizeof (val));
175 	val.type = ev_func;
176 	val.v.func_val.val = func_val;
177 	val.v.func_val.type = type;
178 	return find_value (&val);
179 }
180 
181 ex_value_t *
new_pointer_val(int pointer_val,type_t * type,def_t * def)182 new_pointer_val (int pointer_val, type_t *type, def_t *def)
183 {
184 	ex_value_t  val;
185 	memset (&val, 0, sizeof (val));
186 	val.type = ev_pointer;
187 	val.v.pointer.val = pointer_val;
188 	val.v.pointer.type = type;
189 	val.v.pointer.def = def;
190 	return find_value (&val);
191 }
192 
193 ex_value_t *
new_quaternion_val(const float * quaternion_val)194 new_quaternion_val (const float *quaternion_val)
195 {
196 	ex_value_t  val;
197 	memset (&val, 0, sizeof (val));
198 	val.type = ev_quat;
199 	QuatCopy (quaternion_val, val.v.quaternion_val);
200 	return find_value (&val);
201 }
202 
203 ex_value_t *
new_integer_val(int integer_val)204 new_integer_val (int integer_val)
205 {
206 	ex_value_t  val;
207 	memset (&val, 0, sizeof (val));
208 	val.type = ev_integer;
209 	val.v.integer_val = integer_val;
210 	return find_value (&val);
211 }
212 
213 ex_value_t *
new_uinteger_val(int uinteger_val)214 new_uinteger_val (int uinteger_val)
215 {
216 	ex_value_t  val;
217 	memset (&val, 0, sizeof (val));
218 	val.type = ev_uinteger;
219 	val.v.uinteger_val = uinteger_val;
220 	return find_value (&val);
221 }
222 
223 ex_value_t *
new_short_val(short short_val)224 new_short_val (short short_val)
225 {
226 	ex_value_t  val;
227 	memset (&val, 0, sizeof (val));
228 	val.type = ev_short;
229 	val.v.short_val = short_val;
230 	return find_value (&val);
231 }
232 
233 ex_value_t *
new_nil_val(type_t * type)234 new_nil_val (type_t *type)
235 {
236 	ex_value_t  val;
237 	memset (&val, 0, sizeof (val));
238 	val.type = low_level_type (type);
239 	if (val.type == ev_pointer|| val.type == ev_field )
240 		val.v.pointer.type = type->t.fldptr.type;
241 	if (val.type == ev_func)
242 		val.v.func_val.type = type;
243 	return find_value (&val);
244 }
245 
246 static hashtab_t *string_imm_defs;
247 static hashtab_t *float_imm_defs;
248 static hashtab_t *vector_imm_defs;
249 static hashtab_t *entity_imm_defs;
250 static hashtab_t *field_imm_defs;
251 static hashtab_t *func_imm_defs;
252 static hashtab_t *pointer_imm_defs;
253 static hashtab_t *quaternion_imm_defs;
254 static hashtab_t *integer_imm_defs;
255 
256 static void
imm_free(void * _imm,void * unused)257 imm_free (void *_imm, void *unused)
258 {
259 	free (_imm);
260 }
261 
262 static uintptr_t
imm_get_hash(const void * _imm,void * _tab)263 imm_get_hash (const void *_imm, void *_tab)
264 {
265 	immediate_t *imm = (immediate_t *) _imm;
266 	hashtab_t  **tab = (hashtab_t **) _tab;
267 
268 	if (tab == &string_imm_defs) {
269 		const char *str = pr.strings->strings + imm->i.string_val;
270 		return str ? Hash_String (str) : 0;
271 	} else if (tab == &float_imm_defs) {
272 		return imm->i.integer_val;
273 	} else if (tab == &vector_imm_defs) {
274 		return Hash_Buffer (&imm->i.vector_val, sizeof (&imm->i.vector_val));
275 	} else if (tab == &entity_imm_defs) {
276 		return imm->i.integer_val;
277 	} else if (tab == &field_imm_defs) {
278 		return Hash_Buffer (&imm->i.pointer, sizeof (&imm->i.pointer));
279 	} else if (tab == &func_imm_defs) {
280 		return imm->i.integer_val;
281 	} else if (tab == &pointer_imm_defs) {
282 		return Hash_Buffer (&imm->i.pointer, sizeof (&imm->i.pointer));
283 	} else if (tab == &quaternion_imm_defs) {
284 		return Hash_Buffer (&imm->i.quaternion_val,
285 							sizeof (&imm->i.quaternion_val));
286 	} else if (tab == &integer_imm_defs) {
287 		return imm->i.integer_val;
288 	} else {
289 		internal_error (0, 0);
290 	}
291 }
292 
293 static int
imm_compare(const void * _imm1,const void * _imm2,void * _tab)294 imm_compare (const void *_imm1, const void *_imm2, void *_tab)
295 {
296 	immediate_t *imm1 = (immediate_t *) _imm1;
297 	immediate_t *imm2 = (immediate_t *) _imm2;
298 	hashtab_t  **tab = (hashtab_t **) _tab;
299 
300 	if (tab == &string_imm_defs) {
301 		const char *str1 = pr.strings->strings + imm1->i.string_val;
302 		const char *str2 = pr.strings->strings + imm2->i.string_val;
303 		return (str1 == str2 || (str1 && str2 && !strcmp (str1, str2)));
304 	} else if (tab == &float_imm_defs) {
305 		return imm1->i.float_val == imm2->i.float_val;
306 	} else if (tab == &vector_imm_defs) {
307 		return VectorCompare (imm1->i.vector_val, imm2->i.vector_val);
308 	} else if (tab == &entity_imm_defs) {
309 		return imm1->i.entity_val == imm2->i.entity_val;
310 	} else if (tab == &field_imm_defs) {
311 		return !memcmp (&imm1->i.pointer, &imm2->i.pointer,
312 						sizeof (imm1->i.pointer));
313 	} else if (tab == &func_imm_defs) {
314 		return imm1->i.func_val == imm2->i.func_val;
315 	} else if (tab == &pointer_imm_defs) {
316 		return !memcmp (&imm1->i.pointer, &imm2->i.pointer,
317 						sizeof (imm1->i.pointer));
318 	} else if (tab == &quaternion_imm_defs) {
319 		return (VectorCompare (imm1->i.quaternion_val,
320 							   imm2->i.quaternion_val)
321 				&& imm1->i.quaternion_val[3] == imm2->i.quaternion_val[3]);
322 	} else if (tab == &integer_imm_defs) {
323 		return imm1->i.integer_val == imm2->i.integer_val;
324 	} else {
325 		internal_error (0, 0);
326 	}
327 }
328 
329 int
ReuseString(const char * str)330 ReuseString (const char *str)
331 {
332 	return strpool_addstr (pr.strings, str);
333 }
334 
335 static float
value_as_float(ex_value_t * value)336 value_as_float (ex_value_t *value)
337 {
338 	if (value->type == ev_uinteger)
339 		return value->v.uinteger_val;
340 	if (value->type == ev_integer)
341 		return value->v.integer_val;
342 	if (value->type == ev_short)
343 		return value->v.short_val;
344 	if (value->type == ev_float)
345 		return value->v.float_val;
346 	return 0;
347 }
348 
349 static int
value_as_int(ex_value_t * value)350 value_as_int (ex_value_t *value)
351 {
352 	if (value->type == ev_uinteger)
353 		return value->v.uinteger_val;
354 	if (value->type == ev_integer)
355 		return value->v.integer_val;
356 	if (value->type == ev_short)
357 		return value->v.short_val;
358 	if (value->type == ev_float)
359 		return value->v.float_val;
360 	return 0;
361 }
362 
363 static unsigned
value_as_uint(ex_value_t * value)364 value_as_uint (ex_value_t *value)
365 {
366 	if (value->type == ev_uinteger)
367 		return value->v.uinteger_val;
368 	if (value->type == ev_integer)
369 		return value->v.integer_val;
370 	if (value->type == ev_short)
371 		return value->v.short_val;
372 	if (value->type == ev_float)
373 		return value->v.float_val;
374 	return 0;
375 }
376 
377 ex_value_t *
convert_value(ex_value_t * value,type_t * type)378 convert_value (ex_value_t *value, type_t *type)
379 {
380 	if (!is_scalar (type) || !is_scalar (ev_types[value->type])) {
381 		error (0, "unable to convert non-scalar value");
382 		return value;
383 	}
384 	if (is_float (type)) {
385 		float       val = value_as_float (value);
386 		return new_float_val (val);
387 	} else if (type->type == ev_short) {
388 		int         val = value_as_int (value);
389 		return new_short_val (val);
390 	} else if (type->type == ev_uinteger) {
391 		unsigned    val = value_as_uint (value);
392 		return new_uinteger_val (val);
393 	} else {
394 		//FIXME handle enums separately?
395 		int         val = value_as_int (value);
396 		return new_integer_val (val);
397 	}
398 }
399 
400 ex_value_t *
alias_value(ex_value_t * value,type_t * type)401 alias_value (ex_value_t *value, type_t *type)
402 {
403 	ex_value_t  new;
404 
405 	if (type_size (type) != type_size (ev_types[value->type])) {
406 		error (0, "unable to alias different sized values");
407 		return value;
408 	}
409 	new = *value;
410 	new.type = type->type;
411 	return find_value (&new);
412 }
413 
414 static immediate_t *
make_def_imm(def_t * def,hashtab_t * tab,ex_value_t * val)415 make_def_imm (def_t *def, hashtab_t *tab, ex_value_t *val)
416 {
417 	immediate_t *imm;
418 
419 	imm = calloc (1, sizeof (immediate_t));
420 	imm->def = def;
421 	memcpy (&imm->i, &val->v, sizeof (imm->i));
422 
423 	Hash_AddElement (tab, imm);
424 
425 	return imm;
426 }
427 
428 def_t *
emit_value(ex_value_t * value,def_t * def)429 emit_value (ex_value_t *value, def_t *def)
430 {
431 	def_t      *cn;
432 	hashtab_t  *tab = 0;
433 	type_t     *type;
434 	ex_value_t  val = *value;
435 	immediate_t *imm, search;
436 
437 	if (!string_imm_defs) {
438 		clear_immediates ();
439 	}
440 	cn = 0;
441 	if (val.type == ev_void)
442 		val.type = type_nil->type;
443 	switch (val.type) {
444 		case ev_entity:
445 			tab = entity_imm_defs;
446 			type = &type_entity;
447 			break;
448 		case ev_field:
449 			tab = field_imm_defs;
450 			type = &type_field;
451 			break;
452 		case ev_func:
453 			tab = func_imm_defs;
454 			type = &type_function;
455 			break;
456 		case ev_pointer:
457 			tab = pointer_imm_defs;
458 			type = &type_pointer;
459 			break;
460 		case ev_integer:
461 		case ev_uinteger:
462 			if (!def || def->type != &type_float) {
463 				tab = integer_imm_defs;
464 				type = &type_integer;
465 				break;
466 			}
467 			val.v.float_val = val.v.integer_val;
468 			val.type = ev_float;
469 		case ev_float:
470 			tab = float_imm_defs;
471 			type = &type_float;
472 			break;
473 		case ev_string:
474 			val.v.integer_val = ReuseString (val.v.string_val);
475 			tab = string_imm_defs;
476 			type = &type_string;
477 			break;
478 		case ev_vector:
479 			tab = vector_imm_defs;
480 			type = &type_vector;
481 			break;
482 		case ev_quat:
483 			tab = quaternion_imm_defs;
484 			type = &type_quaternion;
485 			break;
486 		default:
487 			internal_error (0, 0);
488 	}
489 	memcpy (&search.i, &val.v, sizeof (search.i));
490 	imm = (immediate_t *) Hash_FindElement (tab, &search);
491 	if (imm && strcmp (imm->def->name, ".zero") == 0) {
492 		if (def) {
493 			imm = 0;	//FIXME do full def aliasing
494 		} else {
495 			symbol_t   *sym;
496 			sym = make_symbol (".zero", &type_zero, 0, sc_extern);
497 			return sym->s.def;
498 		}
499 	}
500 	if (imm) {
501 		cn = imm->def;
502 		if (def) {
503 			defspace_free_loc (def->space, def->offset, type_size (def->type));
504 			def->offset = cn->offset;
505 			def->initialized = def->constant = 1;
506 			def->nosave = 1;
507 			def->local = 0;
508 			cn = def;
509 		} else {
510 			if (cn->type != type) {
511 				def = new_def (".imm", type, pr.near_data, sc_static);
512 				def->offset = cn->offset;
513 				cn = def;
514 			}
515 		}
516 		return cn;
517 	}
518 	// allocate a new one
519 	// always share immediates
520 	if (def) {
521 		if (def->type != type) {
522 			cn = new_def (".imm", type, pr.near_data, sc_static);
523 			cn->offset = def->offset;
524 		} else {
525 			cn = def;
526 		}
527 	} else {
528 		cn = new_def (".imm", type, pr.near_data, sc_static);
529 	}
530 	cn->initialized = cn->constant = 1;
531 	cn->nosave = 1;
532 	// copy the immediate to the global area
533 	switch (val.type) {
534 		case ev_string:
535 			reloc_def_string (cn);
536 			break;
537 		case ev_func:
538 			if (val.v.func_val.val) {
539 				reloc_t    *reloc;
540 				reloc = new_reloc (cn->space, cn->offset, rel_def_func);
541 				reloc->next = pr.relocs;
542 				pr.relocs = reloc;
543 			}
544 			break;
545 		case ev_field:
546 			if (val.v.pointer.def)
547 				reloc_def_field_ofs (val.v.pointer.def, cn);
548 			break;
549 		case ev_pointer:
550 			if (val.v.pointer.def) {
551 				EMIT_DEF_OFS (pr.near_data, D_INT (cn),
552 							  val.v.pointer.def);
553 			}
554 			break;
555 		default:
556 			break;
557 	}
558 
559 	memcpy (D_POINTER (void, cn), &val.v, 4 * type_size (type));
560 
561 	imm = make_def_imm (cn, tab, &val);
562 
563 	return cn;
564 }
565 
566 void
clear_immediates(void)567 clear_immediates (void)
568 {
569 	def_t      *def;
570 	ex_value_t  zero_val;
571 
572 	if (value_table) {
573 		Hash_FlushTable (value_table);
574 		Hash_FlushTable (string_imm_defs);
575 		Hash_FlushTable (float_imm_defs);
576 		Hash_FlushTable (vector_imm_defs);
577 		Hash_FlushTable (entity_imm_defs);
578 		Hash_FlushTable (field_imm_defs);
579 		Hash_FlushTable (func_imm_defs);
580 		Hash_FlushTable (pointer_imm_defs);
581 		Hash_FlushTable (quaternion_imm_defs);
582 		Hash_FlushTable (integer_imm_defs);
583 	} else {
584 		value_table = Hash_NewTable (16381, 0, 0, 0);
585 		Hash_SetHashCompare (value_table, value_get_hash, value_compare);
586 
587 		string_imm_defs = Hash_NewTable (16381, 0, imm_free, &string_imm_defs);
588 		Hash_SetHashCompare (string_imm_defs, imm_get_hash, imm_compare);
589 
590 		float_imm_defs = Hash_NewTable (16381, 0, imm_free, &float_imm_defs);
591 		Hash_SetHashCompare (float_imm_defs, imm_get_hash, imm_compare);
592 
593 		vector_imm_defs = Hash_NewTable (16381, 0, imm_free, &vector_imm_defs);
594 		Hash_SetHashCompare (vector_imm_defs, imm_get_hash, imm_compare);
595 
596 		entity_imm_defs = Hash_NewTable (16381, 0, imm_free, &entity_imm_defs);
597 		Hash_SetHashCompare (entity_imm_defs, imm_get_hash, imm_compare);
598 
599 		field_imm_defs = Hash_NewTable (16381, 0, imm_free, &field_imm_defs);
600 		Hash_SetHashCompare (field_imm_defs, imm_get_hash, imm_compare);
601 
602 		func_imm_defs = Hash_NewTable (16381, 0, imm_free, &func_imm_defs);
603 		Hash_SetHashCompare (func_imm_defs, imm_get_hash, imm_compare);
604 
605 		pointer_imm_defs =
606 			Hash_NewTable (16381, 0, imm_free, &pointer_imm_defs);
607 		Hash_SetHashCompare (pointer_imm_defs, imm_get_hash, imm_compare);
608 
609 		quaternion_imm_defs =
610 			Hash_NewTable (16381, 0, imm_free, &quaternion_imm_defs);
611 		Hash_SetHashCompare (quaternion_imm_defs, imm_get_hash, imm_compare);
612 
613 		integer_imm_defs =
614 			Hash_NewTable (16381, 0, imm_free, &integer_imm_defs);
615 		Hash_SetHashCompare (integer_imm_defs, imm_get_hash, imm_compare);
616 	}
617 
618 	def = make_symbol (".zero", &type_zero, 0, sc_extern)->s.def;
619 
620 	memset (&zero_val, 0, sizeof (zero_val));
621 	make_def_imm (def, string_imm_defs, &zero_val);
622 	make_def_imm (def, float_imm_defs, &zero_val);
623 	make_def_imm (def, entity_imm_defs, &zero_val);
624 	make_def_imm (def, pointer_imm_defs, &zero_val);
625 	make_def_imm (def, integer_imm_defs, &zero_val);
626 }
627