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