]> gitweb.factorcode.org Git - factor.git/blob - vm/instruction_operands.hpp
Fixes #2966
[factor.git] / vm / instruction_operands.hpp
1 namespace factor {
2
3 enum relocation_type {
4   // arg is a literal table index, holding a pair (symbol/dll)
5   RT_DLSYM,
6   // a word or quotation's general entry point
7   RT_ENTRY_POINT,
8   // a word's PIC entry point
9   RT_ENTRY_POINT_PIC,
10   // a word's tail-call PIC entry point
11   RT_ENTRY_POINT_PIC_TAIL,
12   // current offset
13   RT_HERE,
14   // current code block
15   RT_THIS,
16   // data heap literal
17   RT_LITERAL,
18   // untagged fixnum literal
19   RT_UNTAGGED,
20   // address of megamorphic_cache_hits var
21   RT_MEGAMORPHIC_CACHE_HITS,
22   // address of vm object
23   RT_VM,
24   // value of vm->cards_offset
25   RT_CARDS_OFFSET,
26   // value of vm->decks_offset
27   RT_DECKS_OFFSET,
28   RT_UNUSED,
29   // arg is a literal table index, holding a pair (symbol/dll)
30   RT_DLSYM_TOC,
31   // address of inline_cache_miss function. This is a separate
32   // relocation to reduce compile time and size for PICs.
33   RT_INLINE_CACHE_MISS,
34   // address of safepoint page in code heap
35   RT_SAFEPOINT
36 };
37
38 enum relocation_class {
39   // absolute address in a pointer-width location
40   RC_ABSOLUTE_CELL,
41   // absolute address in a 4 byte location
42   RC_ABSOLUTE,
43   // relative address in a 4 byte location
44   RC_RELATIVE,
45   // absolute address in a PowerPC LIS/ORI sequence
46   RC_ABSOLUTE_PPC_2_2,
47   // absolute address in a PowerPC LWZ instruction
48   RC_ABSOLUTE_PPC_2,
49   // relative address in a PowerPC LWZ/STW/BC instruction
50   RC_RELATIVE_PPC_2_PC,
51   // relative address in a PowerPC B/BL instruction
52   RC_RELATIVE_PPC_3_PC,
53   // relative address in an ARM32 B/BL instruction
54   RC_RELATIVE_ARM_3,
55   // pointer to address in an ARM32 LDR/STR instruction
56   RC_INDIRECT_ARM,
57   // pointer to address in an ARM32 LDR/STR instruction offset by 8 bytes
58   RC_INDIRECT_ARM_PC,
59   // absolute address in a 2 byte location
60   RC_ABSOLUTE_2,
61   // absolute address in a 1 byte location
62   RC_ABSOLUTE_1,
63   // absolute address in a PowerPC LIS/ORI/SLDI/ORIS/ORI sequence
64   RC_ABSOLUTE_PPC_2_2_2_2,
65   // relative address in an ARM64 B/BL instruction
66   RC_RELATIVE_ARM64_BRANCH,
67   // relative address in an ARM64 B.cond instruction
68   RC_RELATIVE_ARM64_BCOND,
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 static const cell rel_relative_arm64_branch_mask = 0x03ffffff;
77 static const cell rel_relative_arm64_bcond_mask = 0x00ffffe0;
78
79 // code relocation table consists of a table of entries for each fixup
80 struct relocation_entry {
81   uint32_t value;
82
83   explicit relocation_entry(uint32_t value) : value(value) {}
84
85   relocation_entry(relocation_type rel_type, relocation_class rel_class,
86                    cell offset) {
87     value = (uint32_t)((rel_type << 28) | (rel_class << 24) | offset);
88   }
89
90   relocation_type type() {
91     return (relocation_type)((value & 0xf0000000) >> 28);
92   }
93
94   relocation_class klass() {
95     return (relocation_class)((value & 0x0f000000) >> 24);
96   }
97
98   cell offset() { return (value & 0x00ffffff); }
99
100   int number_of_parameters() {
101     switch (type()) {
102       case RT_VM:
103         return 1;
104       case RT_DLSYM:
105       case RT_DLSYM_TOC:
106         return 2;
107       case RT_ENTRY_POINT:
108       case RT_ENTRY_POINT_PIC:
109       case RT_ENTRY_POINT_PIC_TAIL:
110       case RT_LITERAL:
111       case RT_HERE:
112       case RT_UNTAGGED:
113       case RT_THIS:
114       case RT_MEGAMORPHIC_CACHE_HITS:
115       case RT_CARDS_OFFSET:
116       case RT_DECKS_OFFSET:
117       case RT_INLINE_CACHE_MISS:
118       case RT_SAFEPOINT:
119         return 0;
120       default:
121         critical_error("Bad rel type in number_of_parameters()", type());
122         return -1; // Can't happen
123     }
124   }
125 };
126
127 struct instruction_operand {
128   relocation_entry rel;
129   code_block* compiled;
130   cell index;
131   cell pointer;
132
133   instruction_operand(relocation_entry rel, code_block* compiled,
134                       cell index);
135
136   fixnum load_value_2_2();
137   fixnum load_value_2_2_2_2();
138   fixnum load_value_masked(cell mask, cell preshift, cell bits, cell postshift);
139   fixnum load_value(cell relative_to);
140   code_block* load_code_block();
141
142   void store_value_2_2(fixnum value);
143   void store_value_2_2_2_2(fixnum value);
144   void store_value_masked(fixnum value, cell mask, cell shift1, cell shift2);
145   void store_value(fixnum value);
146 };
147
148 }