annotate src/insn_rel.c @ 159:71561c12b20b

Updated docs to reflect new cescapes pragma and discuss implicit assumption of the bss section flag for sections named bss and .bss
author lost
date Sat, 31 Jan 2009 06:32:27 +0000
parents f59c0916753d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
29
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
1 /*
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
2 insn_rel.c
33
74a3fef7c8d0 Added general addressing modes (immediate, base page, extended, indexed)
lost
parents: 32
diff changeset
3 Copyright © 2009 William Astle
29
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
4
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
5 This file is part of LWASM.
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
6
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
7 LWASM is free software: you can redistribute it and/or modify it under the
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
8 terms of the GNU General Public License as published by the Free Software
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
9 Foundation, either version 3 of the License, or (at your option) any later
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
10 version.
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
11
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
12 This program is distributed in the hope that it will be useful, but WITHOUT
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
15 more details.
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
16
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
17 You should have received a copy of the GNU General Public License along with
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
18 this program. If not, see <http://www.gnu.org/licenses/>.
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
19 */
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
20
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
21 /*
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
22 for handling relative mode instructions
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
23 */
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
24
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents: 29
diff changeset
25 #define __insn_rel_c_seen__
29
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
26
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
27 #include <stdlib.h>
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
28
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
29 #include "expr.h"
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
30 #include "lwasm.h"
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
31 #include "instab.h"
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
32
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
33 OPFUNC(insn_rel8)
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
34 {
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
35 int v;
77
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
36 lwasm_expr_term_t *t;
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
37 int r;
29
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
38
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
39 lwasm_emitop(as, l, instab[opnum].ops[0]);
77
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
40
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
41 if ((r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST, &v, 0)) < 0)
77
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
42 v = 0;
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
43 else
29
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
44 {
77
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
45 if (as -> passnum == 1)
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
46 {
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
47 // need to adjust the expression
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
48 if (l -> exprs[0])
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
49 {
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
50 t = lwasm_expr_term_create_int(as -> addr + 1);
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
51 lwasm_expr_stack_push(l -> exprs[0], t);
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
52 lwasm_expr_term_free(t);
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
53 t = lwasm_expr_term_create_oper(LWASM_OPER_MINUS);
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
54 lwasm_expr_stack_push(l -> exprs[0], t);
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
55 lwasm_expr_term_free(t);
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
56 }
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
57 else
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
58 {
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
59 l -> exprvals[0] -= as -> addr + 1;
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
60 }
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
61 }
29
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
62 }
77
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
63 if (r == 1 && as -> passnum == 2)
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
64 {
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
65 register_error(as, l, 2, "Illegal external or intersegment reference");
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
66 }
29
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
67 if (v < -128 || v > 127)
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
68 register_error(as, l, 2, "Byte overflow");
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
69 lwasm_emit(as, l, v & 0xff);
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
70 }
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
71
77
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
72 /*
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
73 External and intersegment references are adjusted for the relative addressing mode
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
74 by adjusting the expression on pass 1 and then treated as absolute references later
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
75 */
29
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
76 OPFUNC(insn_rel16)
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
77 {
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
78 int v;
77
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
79 int r;
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
80 lwasm_expr_term_t *t;
29
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
81
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
82 lwasm_emitop(as, l, instab[opnum].ops[0]);
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
83
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
84 r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST, &v, 0);
83
964d68cde469 Fixed problems with re8 and rel16 addressing
lost
parents: 77
diff changeset
85 if (r < 0)
59
89657cb3fdf8 Moved insn_rel.c to simplified expression evaluation
lost
parents: 37
diff changeset
86 v = 0;
77
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
87 else
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
88 {
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
89 if (as -> passnum == 1)
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
90 {
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
91 // need to adjust the expression
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
92 if (l -> exprs[0])
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
93 {
83
964d68cde469 Fixed problems with re8 and rel16 addressing
lost
parents: 77
diff changeset
94 t = lwasm_expr_term_create_int(as -> addr + 2);
77
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
95 lwasm_expr_stack_push(l -> exprs[0], t);
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
96 lwasm_expr_term_free(t);
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
97 t = lwasm_expr_term_create_oper(LWASM_OPER_MINUS);
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
98 lwasm_expr_stack_push(l -> exprs[0], t);
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
99 lwasm_expr_term_free(t);
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
100 }
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
101 else
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
102 {
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
103 l -> exprvals[0] -= as -> addr + 2;
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
104 }
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
105 }
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
106 }
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
107 if (as -> passnum == 2 && r == 1)
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
108 {
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
109 // since we have a reference outside this section, add
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
110 // a subtract of the section base to get the right value
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
111 // upon linking
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
112 t = lwasm_expr_term_create_secbase();
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
113 lwasm_expr_stack_push(l -> exprs[0], t);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
114 lwasm_expr_term_free(t);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
115 t = lwasm_expr_term_create_oper(LWASM_OPER_MINUS);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
116 lwasm_expr_stack_push(l -> exprs[0], t);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
117 lwasm_expr_term_free(t);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
118
77
a338d496350e Checkpointing conversion to allow object target
lost
parents: 59
diff changeset
119 l -> relocoff = as -> addr - l -> codeaddr;
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 98
diff changeset
120 }
29
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
121 lwasm_emit(as, l, (v >> 8) & 0xff);
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
122 lwasm_emit(as, l, v & 0xff);
37aec845aef3 Added relative addressing handler
lost
parents:
diff changeset
123 }