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