1 // $Id: operands.c,v 1.11 2004/02/02 00:13:46 iain Exp $
6 git_uint32 parseLoad (git_uint32 * pc, LoadReg reg, int mode, TransferSize size, git_sint32 * constVal)
12 case 0x0: // Constant zero. (Zero bytes)
16 case 0x1: // Constant, -80 to 7F. (One byte)
17 value = (git_sint32) ((git_sint8) memRead8(*pc));
21 case 0x2: // Constant, -8000 to 7FFF. (Two bytes)
22 value = (git_sint32) ((git_sint16) memRead16(*pc));
26 case 0x3: // Constant, any value. (Four bytes)
27 value = memRead32(*pc);
31 case 0x5: // Contents of address 00 to FF. (One byte)
32 value = memRead8(*pc);
36 case 0x6: // Contents of address 0000 to FFFF. (Two bytes)
37 value = memRead16(*pc);
41 case 0x7: // Contents of any address. (Four bytes)
42 value = memRead32(*pc);
46 case 0x8: // Value popped off stack. (Zero bytes)
49 case 0x9: // Call frame local at address 00 to FF. (One byte)
50 value = memRead8(*pc);
54 case 0xA: // Call frame local at address 0000 to FFFF. (Two bytes)
55 value = memRead16(*pc);
59 case 0xB: // Call frame local at any address. (Four bytes)
60 value = memRead32(*pc);
64 case 0xD: // Contents of RAM address 00 to FF. (One byte)
65 value = memRead8(*pc) + gRamStart;
69 case 0xE: // Contents of RAM address 0000 to FFFF. (Two bytes)
70 value = memRead16(*pc) + gRamStart;
74 case 0xF: // Contents of RAM, any address. (Four bytes)
75 value = memRead32(*pc) + gRamStart;
79 default: // Illegal addressing mode
83 // ------------------------------------------------------
93 emitCode (label_L1_const + reg);
99 emitCode (label_L1_stack + reg);
103 if (value < gRamStart)
106 value = memRead32(value);
107 else if (size == size16)
108 value = memRead16(value);
110 value = memRead8(value);
116 assert (reg == reg_L1);
117 emitCode (label_L1_addr8);
121 assert (reg == reg_L1);
122 emitCode (label_L1_addr16);
126 emitCode (label_L1_addr + reg);
133 emitCode (label_L1_local + reg);
134 emitData (value / 4); // Convert byte offset to word offset.
141 void parseStore (git_uint32 * pc, StoreReg reg, int mode, TransferSize size)
150 case 0x5: // Contents of address 00 to FF. (One byte)
151 value = memRead8(*pc);
155 case 0x6: // Contents of address 0000 to FFFF. (Two bytes)
156 value = memRead16(*pc);
160 case 0x7: // Contents of any address. (Four bytes)
161 value = memRead32(*pc);
165 case 0x8: // Value popped off stack. (Zero bytes)
168 case 0x9: // Call frame local at store_address 00 to FF. (One byte)
169 value = memRead8(*pc);
173 case 0xA: // Call frame local at store_address 0000 to FFFF. (Two bytes)
174 value = memRead16(*pc);
178 case 0xB: // Call frame local at any store_address. (Four bytes)
179 value = memRead32(*pc);
183 case 0xD: // Contents of RAM address 00 to FF. (One byte)
184 value = memRead8(*pc) + gRamStart;
188 case 0xE: // Contents of RAM address 0000 to FFFF. (Two bytes)
189 value = memRead16(*pc) + gRamStart;
193 case 0xF: // Contents of RAM, any address. (Four bytes)
194 value = memRead32(*pc) + gRamStart;
198 // ------------------------------------------------------
201 emitCode (reg == reg_S1 ? label_S1_stack : label_S2_stack);
207 emitCode (reg == reg_S1 ? label_S1_addr : label_S2_addr);
211 assert (reg == reg_S1);
212 emitCode (size == size16 ? label_S1_addr16 : label_S1_addr8);
218 emitCode (reg == reg_S1 ? label_S1_local : label_S2_local);
219 emitData (value / 4); // Convert byte offset to word offset.
224 static void parseStub (git_uint32 * pc, int mode, Label discardOp)
231 case 0x5: // Contents of address 00 to FF. (One byte)
232 value = memRead8(*pc);
235 case 0x6: // Contents of address 0000 to FFFF. (Two bytes)
236 value = memRead16(*pc);
239 case 0x7: // Contents of any address. (Four bytes)
240 value = memRead32(*pc);
243 case 0x8: // Value popped off stack. (Zero bytes)
245 case 0x9: // Call frame local at store_address 00 to FF. (One byte)
246 value = memRead8(*pc);
249 case 0xA: // Call frame local at store_address 0000 to FFFF. (Two bytes)
250 value = memRead16(*pc);
253 case 0xB: // Call frame local at any store_address. (Four bytes)
254 value = memRead32(*pc);
257 case 0xD: // Contents of RAM address 00 to FF. (One byte)
258 value = memRead8(*pc) + gRamStart;
261 case 0xE: // Contents of RAM address 0000 to FFFF. (Two bytes)
262 value = memRead16(*pc) + gRamStart;
265 case 0xF: // Contents of RAM, any address. (Four bytes)
266 value = memRead32(*pc) + gRamStart;
269 // ------------------------------------------------------
271 emitCode (discardOp);
274 emitCode (discardOp + (label_call_stub_stack - label_call_stub_discard));
277 emitCode (discardOp + (label_call_stub_addr - label_call_stub_discard));
281 emitCode (discardOp + (label_call_stub_local - label_call_stub_discard));
286 // Every call stub ends with the glulx return address.
289 // ...which means that every call stub references the next instruction.
290 nextInstructionIsReferenced ();
292 void parseCallStub (git_uint32 * pc, int mode)
294 parseStub (pc, mode, label_call_stub_discard);
296 void parseSaveStub (git_uint32 * pc, int mode)
298 parseStub (pc, mode, label_save_stub_discard);
300 void parseUndoStub (git_uint32 * pc, int mode)
302 parseStub (pc, mode, label_undo_stub_discard);
305 void parseCatchStub (git_uint32 * pc, int * modes)
307 git_uint32 tokenVal, branchVal;
308 git_uint32 branchConst = 0;
315 case 0x5: // Contents of address 00 to FF. (One byte)
316 tokenVal = memRead8(*pc);
319 case 0x6: // Contents of address 0000 to FFFF. (Two bytes)
320 tokenVal = memRead16(*pc);
323 case 0x7: // Contents of any address. (Four bytes)
324 tokenVal = memRead32(*pc);
327 case 0x8: // Value popped off stack. (Zero bytes)
329 case 0x9: // Call frame local at store_address 00 to FF. (One byte)
330 tokenVal = memRead8(*pc);
333 case 0xA: // Call frame local at store_address 0000 to FFFF. (Two bytes)
334 tokenVal = memRead16(*pc);
337 case 0xB: // Call frame local at any store_address. (Four bytes)
338 tokenVal = memRead32(*pc);
341 case 0xD: // Contents of RAM address 00 to FF. (One byte)
342 tokenVal = memRead8(*pc) + gRamStart;
345 case 0xE: // Contents of RAM address 0000 to FFFF. (Two bytes)
346 tokenVal = memRead16(*pc) + gRamStart;
349 case 0xF: // Contents of RAM, any address. (Four bytes)
350 tokenVal = memRead32(*pc) + gRamStart;
353 // ------------------------------------------------------
355 branchConst = parseLoad (pc, reg_L1, modes[1], size32, &branchVal);
356 emitCode (label_catch_stub_discard);
359 branchConst = parseLoad (pc, reg_L1, modes[1], size32, &branchVal);
360 emitCode (label_catch_stub_stack);
363 branchConst = parseLoad (pc, reg_L1, modes[1], size32, &branchVal);
364 emitCode (label_catch_stub_addr);
368 branchConst = parseLoad (pc, reg_L1, modes[1], size32, &branchVal);
369 emitCode (label_catch_stub_local);
374 // The catch stub ends with the address to go to on throw,
375 // which is after the branch, so we don't know what it is yet.
377 stubCode = peekAtEmittedStuff (1);
379 // Emit the branch taken after storing the catch token.
383 emitCode (label_jump_return0);
384 else if (branchVal == 1)
385 emitCode (label_jump_return1);
387 emitConstBranch (label_jump_const, *pc + branchVal - 2);
391 emitCode (label_jump_var);
395 // Fix up the throw return address
397 nextInstructionIsReferenced ();