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