comparison lwasm/pass5.c @ 0:2c24602be78f

Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
author lost@l-w.ca
date Wed, 19 Jan 2011 22:27:17 -0700
parents
children 7317fbe024af
comparison
equal deleted inserted replaced
-1:000000000000 0:2c24602be78f
1 /*
2 pass5.c
3
4 Copyright © 2010 William Astle
5
6 This file is part of LWTOOLS.
7
8 LWTOOLS is free software: you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation, either version 3 of the License, or (at your option) any later
11 version.
12
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 more details.
17
18 You should have received a copy of the GNU General Public License along with
19 this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <stdio.h>
23 #include <string.h>
24
25 #include <lw_alloc.h>
26 #include <lw_string.h>
27
28 #include "lwasm.h"
29 #include "instab.h"
30
31 /*
32 AssignAddresses Pass
33
34 Force resolution of all line addresses
35
36 */
37
38 static int exprok_aux(lw_expr_t e, void *priv)
39 {
40 asmstate_t *as = priv;
41
42 if (lw_expr_istype(e, lw_expr_type_int))
43 return 0;
44 if (lw_expr_istype(e, lw_expr_type_oper))
45 return 0;
46 if (lw_expr_istype(e, lw_expr_type_special) && as -> output_format == OUTPUT_OBJ)
47 {
48 int t;
49 t = lw_expr_specint(e);
50 if (t == lwasm_expr_secbase)
51 return 0;
52 }
53
54 return 1;
55 }
56
57 static int exprok(asmstate_t *as, lw_expr_t e)
58 {
59 if (lw_expr_testterms(e, exprok_aux, as))
60 return 0;
61 return 1;
62 }
63
64 void do_pass5(asmstate_t *as)
65 {
66 int rc;
67 int cnt;
68 int ocnt;
69 line_t *cl, *sl;
70 struct line_expr_s *le;
71
72 // first, count the number of non-constant addresses; do
73 // a reduction first on each one
74 for (cnt = 0, cl = as -> line_head; cl; cl = cl -> next)
75 {
76 as -> cl = cl;
77 lwasm_reduce_expr(as, cl -> addr);
78 if (!exprok(as, cl -> addr))
79 cnt++;
80 }
81
82 sl = as -> line_head;
83 while (cnt > 0)
84 {
85 ocnt = cnt;
86
87 // find an unresolved address
88 for ( ; sl && exprok(as, sl -> addr); sl = sl -> next)
89 /* do nothing */ ;
90
91 // simplify address
92 for (cl = sl; cl; cl = cl -> next)
93 {
94 as -> cl = sl;
95 lwasm_reduce_expr(as, sl -> addr);
96
97 if (exprok(as, cl -> addr))
98 {
99 if (0 == --cnt);
100 return;
101 }
102 }
103
104 if (cnt == ocnt)
105 break;
106 }
107
108 if (cnt)
109 {
110 // we have non-resolved line addresses here
111 for (cl = sl; cl; cl = cl -> next)
112 {
113 if (!exprok(as, cl -> addr))
114 {
115 lwasm_register_error(as, cl, "Cannot resolve line address");
116 }
117 }
118 }
119 }