]> gitweb.factorcode.org Git - factor.git/blob - vm/instruction_operands.hpp
Merge branch 'master' of factorcode.org:/git/factor
[factor.git] / vm / instruction_operands.hpp
1 namespace factor
2 {
3
4 enum relocation_type {
5         /* arg is a literal table index, holding a pair (symbol/dll) */
6         RT_DLSYM,
7         /* a word or quotation's general entry point */
8         RT_ENTRY_POINT,
9         /* a word's PIC entry point */
10         RT_ENTRY_POINT_PIC,
11         /* a word's tail-call PIC entry point */
12         RT_ENTRY_POINT_PIC_TAIL,
13         /* current offset */
14         RT_HERE,
15         /* current code block */
16         RT_THIS,
17         /* data heap literal */
18         RT_LITERAL,
19         /* untagged fixnum literal */
20         RT_UNTAGGED,
21         /* address of megamorphic_cache_hits var */
22         RT_MEGAMORPHIC_CACHE_HITS,
23         /* address of vm object */
24         RT_VM,
25         /* value of vm->cards_offset */
26         RT_CARDS_OFFSET,
27         /* value of vm->decks_offset */
28         RT_DECKS_OFFSET,
29         /* address of exception_handler -- this exists as a separate relocation
30         type since its used in a situation where relocation arguments cannot
31         be passed in, and so RT_DLSYM is inappropriate (Windows only) */
32         RT_EXCEPTION_HANDLER,
33 };
34
35 enum relocation_class {
36         /* absolute address in a pointer-width location */
37         RC_ABSOLUTE_CELL,
38         /* absolute address in a 4 byte location */
39         RC_ABSOLUTE,
40         /* relative address in a 4 byte location */
41         RC_RELATIVE,
42         /* absolute address in a PowerPC LIS/ORI sequence */
43         RC_ABSOLUTE_PPC_2_2,
44         /* absolute address in a PowerPC LWZ instruction */
45         RC_ABSOLUTE_PPC_2,
46         /* relative address in a PowerPC LWZ/STW/BC instruction */
47         RC_RELATIVE_PPC_2,
48         /* relative address in a PowerPC B/BL instruction */
49         RC_RELATIVE_PPC_3,
50         /* relative address in an ARM B/BL instruction */
51         RC_RELATIVE_ARM_3,
52         /* pointer to address in an ARM LDR/STR instruction */
53         RC_INDIRECT_ARM,
54         /* pointer to address in an ARM LDR/STR instruction offset by 8 bytes */
55         RC_INDIRECT_ARM_PC,
56         /* absolute address in a 2 byte location */
57         RC_ABSOLUTE_2,
58         /* absolute address in a 1 byte location */
59         RC_ABSOLUTE_1,
60 };
61
62 static const cell rel_absolute_ppc_2_mask = 0xffff;
63 static const cell rel_relative_ppc_2_mask = 0xfffc;
64 static const cell rel_relative_ppc_3_mask = 0x3fffffc;
65 static const cell rel_indirect_arm_mask = 0xfff;
66 static const cell rel_relative_arm_3_mask = 0xffffff;
67
68 /* code relocation table consists of a table of entries for each fixup */
69 struct relocation_entry {
70         u32 value;
71
72         explicit relocation_entry(u32 value_) : value(value_) {}
73
74         relocation_entry(relocation_type rel_type,
75                 relocation_class rel_class,
76                 cell offset)
77         {
78                 value = (u32)((rel_type << 28) | (rel_class << 24) | offset);
79         }
80
81         relocation_type rel_type()
82         {
83                 return (relocation_type)((value & 0xf0000000) >> 28);
84         }
85
86         relocation_class rel_class()
87         {
88                 return (relocation_class)((value & 0x0f000000) >> 24);
89         }
90
91         cell rel_offset()
92         {
93                 return (value & 0x00ffffff);
94         }
95
96         int number_of_parameters()
97         {
98                 switch(rel_type())
99                 {
100                 case RT_VM:
101                         return 1;
102                 case RT_DLSYM:
103                         return 2;
104                 case RT_ENTRY_POINT:
105                 case RT_ENTRY_POINT_PIC:
106                 case RT_ENTRY_POINT_PIC_TAIL:
107                 case RT_LITERAL:
108                 case RT_HERE:
109                 case RT_UNTAGGED:
110                 case RT_THIS:
111                 case RT_MEGAMORPHIC_CACHE_HITS:
112                 case RT_CARDS_OFFSET:
113                 case RT_DECKS_OFFSET:
114                 case RT_EXCEPTION_HANDLER:
115                         return 0;
116                 default:
117                         critical_error("Bad rel type",rel_type());
118                         return -1; /* Can't happen */
119                 }
120         }
121 };
122
123 struct instruction_operand {
124         relocation_entry rel;
125         code_block *compiled;
126         cell index;
127         cell pointer;
128
129         instruction_operand(relocation_entry rel_, code_block *compiled_, cell index_);
130
131         relocation_type rel_type()
132         {
133                 return rel.rel_type();
134         }
135
136         cell rel_offset()
137         {
138                 return rel.rel_offset();
139         }
140
141         cell parameter_index()
142         {
143                 return index;
144         }
145
146         code_block *parent_code_block()
147         {
148                 return compiled;
149         }
150
151         fixnum load_value_2_2();
152         fixnum load_value_masked(cell mask, cell bits, cell shift);
153         fixnum load_value(cell relative_to);
154         fixnum load_value();
155         code_block *load_code_block(cell relative_to);
156         code_block *load_code_block();
157
158         void store_value_2_2(fixnum value);
159         void store_value_masked(fixnum value, cell mask, cell shift);
160         void store_value(fixnum value);
161         void store_code_block(code_block *compiled);
162 };
163
164 }