~ubuntu-branches/ubuntu/wily/gargoyle-free/wily-proposed

« back to all changes in this revision

Viewing changes to terps/git/operands.c

  • Committer: Bazaar Package Importer
  • Author(s): Sylvain Beucler
  • Date: 2009-09-11 20:09:43 UTC
  • Revision ID: james.westby@ubuntu.com-20090911200943-idgzoyupq6650zpn
Tags: upstream-2009-08-25
ImportĀ upstreamĀ versionĀ 2009-08-25

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// $Id: operands.c,v 1.11 2004/02/02 00:13:46 iain Exp $
 
2
 
 
3
#include "git.h"
 
4
#include <assert.h>
 
5
 
 
6
git_uint32 parseLoad (git_uint32 * pc, LoadReg reg, int mode, TransferSize size, git_sint32 * constVal)
 
7
{
 
8
    git_uint32 value;
 
9
 
 
10
    switch (mode)
 
11
    {
 
12
        case 0x0: // Constant zero. (Zero bytes)
 
13
            value = 0;
 
14
            goto load_const;
 
15
 
 
16
        case 0x1: // Constant, -80 to 7F. (One byte)
 
17
            value = (git_sint32) ((git_sint8) memRead8(*pc));
 
18
            *pc += 1;
 
19
            goto load_const;
 
20
 
 
21
        case 0x2: // Constant, -8000 to 7FFF. (Two bytes)
 
22
            value = (git_sint32) ((git_sint16) memRead16(*pc));
 
23
            *pc += 2;
 
24
            goto load_const;
 
25
 
 
26
        case 0x3: // Constant, any value. (Four bytes)
 
27
            value = memRead32(*pc);
 
28
            *pc += 4;
 
29
            goto load_const;
 
30
 
 
31
        case 0x5: // Contents of address 00 to FF. (One byte)
 
32
            value = memRead8(*pc);
 
33
            *pc += 1;
 
34
            goto load_addr;
 
35
 
 
36
        case 0x6: // Contents of address 0000 to FFFF. (Two bytes)
 
37
            value = memRead16(*pc);
 
38
            *pc += 2;
 
39
            goto load_addr;
 
40
 
 
41
        case 0x7: // Contents of any address. (Four bytes)
 
42
            value = memRead32(*pc);
 
43
            *pc += 4;
 
44
            goto load_addr;
 
45
 
 
46
        case 0x8: // Value popped off stack. (Zero bytes)
 
47
            goto load_stack;
 
48
 
 
49
        case 0x9: // Call frame local at address 00 to FF. (One byte)
 
50
            value = memRead8(*pc);
 
51
            *pc += 1;
 
52
            goto load_local;
 
53
 
 
54
        case 0xA: // Call frame local at address 0000 to FFFF. (Two bytes)
 
55
            value = memRead16(*pc);
 
56
            *pc += 2;
 
57
            goto load_local;
 
58
 
 
59
        case 0xB: // Call frame local at any address. (Four bytes)
 
60
            value = memRead32(*pc);
 
61
            *pc += 4;
 
62
            goto load_local;
 
63
 
 
64
        case 0xD: // Contents of RAM address 00 to FF. (One byte)
 
65
            value = memRead8(*pc) + gRamStart;
 
66
            *pc += 1;
 
67
            goto load_addr;
 
68
 
 
69
        case 0xE: // Contents of RAM address 0000 to FFFF. (Two bytes)
 
70
            value = memRead16(*pc) + gRamStart;
 
71
            *pc += 2;
 
72
            goto load_addr;
 
73
 
 
74
        case 0xF: // Contents of RAM, any address. (Four bytes)
 
75
            value = memRead32(*pc) + gRamStart;
 
76
            *pc += 4;
 
77
            goto load_addr;
 
78
 
 
79
        default: // Illegal addressing mode
 
80
            abortCompilation();
 
81
            break;
 
82
 
 
83
        // ------------------------------------------------------
 
84
 
 
85
        load_const:
 
86
            if (constVal)
 
87
            {
 
88
                *constVal = value;
 
89
                return 1;
 
90
            }
 
91
            else
 
92
            {
 
93
                emitCode (label_L1_const + reg);
 
94
                emitData (value);
 
95
            }
 
96
            break;
 
97
 
 
98
        load_stack:
 
99
                        emitCode (label_L1_stack + reg);
 
100
                        break;
 
101
 
 
102
        load_addr:
 
103
            if (value < gRamStart)
 
104
            {
 
105
                if (size == size32)
 
106
                    value = memRead32(value);
 
107
                else if (size == size16)
 
108
                    value = memRead16(value);
 
109
                else
 
110
                    value = memRead8(value);
 
111
                                goto load_const;
 
112
            }
 
113
                        switch (size)
 
114
                        {
 
115
                                case size8:
 
116
                                        assert (reg == reg_L1);
 
117
                                        emitCode (label_L1_addr8);
 
118
                                        break;
 
119
 
 
120
                                case size16:
 
121
                                        assert (reg == reg_L1);
 
122
                                        emitCode (label_L1_addr16);
 
123
                                        break;
 
124
 
 
125
                                case size32:
 
126
                                        emitCode (label_L1_addr + reg);
 
127
                                        break;
 
128
                        }
 
129
                        emitData (value);
 
130
                        break;
 
131
 
 
132
        load_local:
 
133
            emitCode (label_L1_local + reg);
 
134
            emitData (value / 4); // Convert byte offset to word offset.
 
135
            break;
 
136
    }
 
137
 
 
138
    return 0;
 
139
}
 
140
 
 
141
void parseStore (git_uint32 * pc, StoreReg reg, int mode, TransferSize size)
 
142
{
 
143
    git_uint32 value;
 
144
 
 
145
    switch (mode)
 
146
    {
 
147
        case 0x0: // Discard
 
148
            break;
 
149
 
 
150
        case 0x5: // Contents of address 00 to FF. (One byte)
 
151
            value = memRead8(*pc);
 
152
            *pc += 1;
 
153
            goto store_addr;
 
154
 
 
155
        case 0x6: // Contents of address 0000 to FFFF. (Two bytes)
 
156
            value = memRead16(*pc);
 
157
            *pc += 2;
 
158
            goto store_addr;
 
159
 
 
160
        case 0x7: // Contents of any address. (Four bytes)
 
161
            value = memRead32(*pc);
 
162
            *pc += 4;
 
163
            goto store_addr;
 
164
 
 
165
        case 0x8: // Value popped off stack. (Zero bytes)
 
166
            goto store_stack;
 
167
 
 
168
        case 0x9: // Call frame local at store_address 00 to FF. (One byte)
 
169
            value = memRead8(*pc);
 
170
            *pc += 1;
 
171
            goto store_local;
 
172
 
 
173
        case 0xA: // Call frame local at store_address 0000 to FFFF. (Two bytes)
 
174
            value = memRead16(*pc);
 
175
            *pc += 2;
 
176
            goto store_local;
 
177
 
 
178
        case 0xB: // Call frame local at any store_address. (Four bytes)
 
179
            value = memRead32(*pc);
 
180
            *pc += 4;
 
181
            goto store_local;
 
182
 
 
183
        case 0xD: // Contents of RAM address 00 to FF. (One byte)
 
184
            value = memRead8(*pc) + gRamStart;
 
185
            *pc += 1;
 
186
            goto store_addr;
 
187
 
 
188
        case 0xE: // Contents of RAM address 0000 to FFFF. (Two bytes)
 
189
            value = memRead16(*pc) + gRamStart;
 
190
            *pc += 2;
 
191
            goto store_addr;
 
192
 
 
193
        case 0xF: // Contents of RAM, any address. (Four bytes)
 
194
            value = memRead32(*pc) + gRamStart;
 
195
            *pc += 4;
 
196
            goto store_addr;
 
197
 
 
198
        // ------------------------------------------------------
 
199
 
 
200
        store_stack:
 
201
            emitCode (reg == reg_S1 ? label_S1_stack : label_S2_stack);
 
202
            break;
 
203
 
 
204
        store_addr:
 
205
            if (size == size32)
 
206
                        {
 
207
                emitCode (reg == reg_S1 ? label_S1_addr : label_S2_addr);
 
208
            }
 
209
                        else
 
210
                        {
 
211
                                assert (reg == reg_S1);
 
212
                                emitCode (size == size16 ? label_S1_addr16 : label_S1_addr8);
 
213
                        }
 
214
            emitData (value);
 
215
            break;
 
216
 
 
217
        store_local:
 
218
            emitCode (reg == reg_S1 ? label_S1_local : label_S2_local);
 
219
            emitData (value / 4); // Convert byte offset to word offset.
 
220
            break;
 
221
    }
 
222
}
 
223
 
 
224
static void parseStub (git_uint32 * pc, int mode, Label discardOp)
 
225
{
 
226
    git_uint32 value;
 
227
    switch (mode)
 
228
    {
 
229
        case 0x0: // Discard
 
230
            goto store_discard;
 
231
        case 0x5: // Contents of address 00 to FF. (One byte)
 
232
            value = memRead8(*pc);
 
233
            *pc += 1;
 
234
            goto store_addr;
 
235
        case 0x6: // Contents of address 0000 to FFFF. (Two bytes)
 
236
            value = memRead16(*pc);
 
237
            *pc += 2;
 
238
            goto store_addr;
 
239
        case 0x7: // Contents of any address. (Four bytes)
 
240
            value = memRead32(*pc);
 
241
            *pc += 4;
 
242
            goto store_addr;
 
243
        case 0x8: // Value popped off stack. (Zero bytes)
 
244
            goto store_stack;
 
245
        case 0x9: // Call frame local at store_address 00 to FF. (One byte)
 
246
            value = memRead8(*pc);
 
247
            *pc += 1;
 
248
            goto store_local;
 
249
        case 0xA: // Call frame local at store_address 0000 to FFFF. (Two bytes)
 
250
            value = memRead16(*pc);
 
251
            *pc += 2;
 
252
            goto store_local;
 
253
        case 0xB: // Call frame local at any store_address. (Four bytes)
 
254
            value = memRead32(*pc);
 
255
            *pc += 4;
 
256
            goto store_local;
 
257
        case 0xD: // Contents of RAM address 00 to FF. (One byte)
 
258
            value = memRead8(*pc) + gRamStart;
 
259
            *pc += 1;
 
260
            goto store_addr;
 
261
        case 0xE: // Contents of RAM address 0000 to FFFF. (Two bytes)
 
262
            value = memRead16(*pc) + gRamStart;
 
263
            *pc += 2;
 
264
            goto store_addr;
 
265
        case 0xF: // Contents of RAM, any address. (Four bytes)
 
266
            value = memRead32(*pc) + gRamStart;
 
267
            *pc += 4;
 
268
            goto store_addr;
 
269
        // ------------------------------------------------------
 
270
        store_discard:
 
271
            emitCode (discardOp);
 
272
            break;
 
273
        store_stack:
 
274
            emitCode (discardOp + (label_call_stub_stack - label_call_stub_discard));
 
275
            break;
 
276
        store_addr:
 
277
            emitCode (discardOp + (label_call_stub_addr - label_call_stub_discard));
 
278
            emitData (value);
 
279
            break;
 
280
        store_local:
 
281
            emitCode (discardOp + (label_call_stub_local - label_call_stub_discard));
 
282
            emitData (value); // Convert byte offset to word offset.
 
283
            break;
 
284
    }
 
285
    
 
286
    // Every call stub ends with the glulx return address.
 
287
    emitData (*pc);
 
288
 
 
289
    // ...which means that every call stub references the next instruction.
 
290
    nextInstructionIsReferenced ();
 
291
}
 
292
void parseCallStub (git_uint32 * pc, int mode)
 
293
{
 
294
    parseStub (pc, mode, label_call_stub_discard);
 
295
}
 
296
void parseCatchStub (git_uint32 * pc, int mode)
 
297
{
 
298
    parseStub (pc, mode, label_catch_stub_discard);
 
299
}
 
300
void parseSaveStub (git_uint32 * pc, int mode)
 
301
{
 
302
    parseStub (pc, mode, label_save_stub_discard);
 
303
}
 
304
void parseUndoStub (git_uint32 * pc, int mode)
 
305
{
 
306
    parseStub (pc, mode, label_undo_stub_discard);
 
307
}