]> gitweb.factorcode.org Git - factor.git/blob - vm/instruction_operands.hpp
vm: add RT_SAFEPOINT relocation type
[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         /* arg is a literal table index, holding a pair (symbol/dll) */
34         RT_DLSYM_TOC,
35         /* address of inline_cache_miss function. This is a separate
36         relocation to reduce compile time and size for PICs. */
37         RT_INLINE_CACHE_MISS,
38         /* address of safepoint page in code heap */
39         RT_SAFEPOINT
40 };
41
42 enum relocation_class {
43         /* absolute address in a pointer-width location */
44         RC_ABSOLUTE_CELL,
45         /* absolute address in a 4 byte location */
46         RC_ABSOLUTE,
47         /* relative address in a 4 byte location */
48         RC_RELATIVE,
49         /* absolute address in a PowerPC LIS/ORI sequence */
50         RC_ABSOLUTE_PPC_2_2,
51         /* absolute address in a PowerPC LWZ instruction */
52         RC_ABSOLUTE_PPC_2,
53         /* relative address in a PowerPC LWZ/STW/BC instruction */
54         RC_RELATIVE_PPC_2_PC,
55         /* relative address in a PowerPC B/BL instruction */
56         RC_RELATIVE_PPC_3_PC,
57         /* relative address in an ARM B/BL instruction */
58         RC_RELATIVE_ARM_3,
59         /* pointer to address in an ARM LDR/STR instruction */
60         RC_INDIRECT_ARM,
61         /* pointer to address in an ARM LDR/STR instruction offset by 8 bytes */
62         RC_INDIRECT_ARM_PC,
63         /* absolute address in a 2 byte location */
64         RC_ABSOLUTE_2,
65         /* absolute address in a 1 byte location */
66         RC_ABSOLUTE_1,
67         /* absolute address in a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence */
68         RC_ABSOLUTE_PPC_2_2_2_2,
69 };
70
71 static const cell rel_absolute_ppc_2_mask = 0x0000ffff;
72 static const cell rel_relative_ppc_2_mask = 0x0000fffc;
73 static const cell rel_relative_ppc_3_mask = 0x03fffffc;
74 static const cell rel_indirect_arm_mask   = 0x00000fff;
75 static const cell rel_relative_arm_3_mask = 0x00ffffff;
76
77 /* code relocation table consists of a table of entries for each fixup */
78 struct relocation_entry {
79         u32 value;
80
81         explicit relocation_entry(u32 value_) : value(value_) {}
82
83         relocation_entry(relocation_type rel_type,
84                 relocation_class rel_class,
85                 cell offset)
86         {
87                 value = (u32)((rel_type << 28) | (rel_class << 24) | offset);
88         }
89
90         relocation_type rel_type()
91         {
92                 return (relocation_type)((value & 0xf0000000) >> 28);
93         }
94
95         relocation_class rel_class()
96         {
97                 return (relocation_class)((value & 0x0f000000) >> 24);
98         }
99
100         cell rel_offset()
101         {
102                 return (value & 0x00ffffff);
103         }
104
105         int number_of_parameters()
106         {
107                 switch(rel_type())
108                 {
109                 case RT_VM:
110                         return 1;
111                 case RT_DLSYM:
112                 case RT_DLSYM_TOC:
113                         return 2;
114                 case RT_ENTRY_POINT:
115                 case RT_ENTRY_POINT_PIC:
116                 case RT_ENTRY_POINT_PIC_TAIL:
117                 case RT_LITERAL:
118                 case RT_HERE:
119                 case RT_UNTAGGED:
120                 case RT_THIS:
121                 case RT_MEGAMORPHIC_CACHE_HITS:
122                 case RT_CARDS_OFFSET:
123                 case RT_DECKS_OFFSET:
124                 case RT_EXCEPTION_HANDLER:
125                 case RT_INLINE_CACHE_MISS:
126                         return 0;
127                 default:
128                         critical_error("Bad rel type in number_of_parameters()",rel_type());
129                         return -1; /* Can't happen */
130                 }
131         }
132 };
133
134 struct instruction_operand {
135         relocation_entry rel;
136         code_block *compiled;
137         cell index;
138         cell pointer;
139
140         instruction_operand(relocation_entry rel_, code_block *compiled_, cell index_);
141
142         relocation_type rel_type()
143         {
144                 return rel.rel_type();
145         }
146
147         cell rel_offset()
148         {
149                 return rel.rel_offset();
150         }
151
152         fixnum load_value_2_2();
153         fixnum load_value_2_2_2_2();
154         fixnum load_value_masked(cell mask, cell bits, cell shift);
155         fixnum load_value(cell relative_to);
156         fixnum load_value();
157         code_block *load_code_block(cell relative_to);
158         code_block *load_code_block();
159
160         void store_value_2_2(fixnum value);
161         void store_value_2_2_2_2(fixnum value);
162         void store_value_masked(fixnum value, cell mask, cell shift);
163         void store_value(fixnum value);
164         void store_code_block(code_block *compiled);
165 };
166
167 }