Revision 367e86e8

b/Makefile
1 1
ARCH=i386
2 2
#ARCH=ppc
3
HOST_CC=gcc
3 4

  
4 5
ifeq ($(ARCH),i386)
5
CFLAGS=-Wall -O2 -g
6
CFLAGS=-Wall -O2 -g -fomit-frame-pointer
6 7
LDFLAGS=-g
7 8
LIBS=
8 9
CC=gcc
......
27 28

  
28 29
#########################################################
29 30

  
30
DEFINES+=-D_GNU_SOURCE -DGEMU -DDOSEMU #-DNO_TRACE_MSGS
31
DEFINES+=-D_GNU_SOURCE -DGEMU -DDOSEMU -DNO_TRACE_MSGS
32
DEFINES+=-DCONFIG_PREFIX=\"/usr/local\"
31 33
LDSCRIPT=$(ARCH).ld
34
LIBS+=-ldl
32 35

  
33 36
OBJS= i386/fp87.o i386/interp_main.o i386/interp_modrm.o i386/interp_16_32.o \
34 37
      i386/interp_32_16.o i386/interp_32_32.o i386/emu-utils.o \
35 38
      i386/dis8086.o i386/emu-ldt.o
39
OBJS+=translate-i386.o op-i386.o
36 40
OBJS+= elfload.o main.o thunk.o syscall.o
37

  
38 41
SRCS = $(OBJS:.o=.c)
39 42

  
40 43
all: gemu
41 44

  
42 45
gemu: $(OBJS)
43
	$(CC) -Wl,-T,$(LDSCRIPT) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
46
	$(CC) -Wl,-T,$(LDSCRIPT) $(LDFLAGS) -o $@ $^ $(LIBS)
44 47

  
45 48
depend: $(SRCS)
46 49
	$(CC) -MM $(CFLAGS) $^ 1>.depend
47 50

  
51
# old i386 emulator
52
i386/interp_32_32.o: i386/interp_32_32.c i386/interp_gen.h
53

  
54
i386/interp_gen.h: i386/gencode
55
	./i386/gencode > $@
56

  
57
i386/gencode: i386/gencode.c
58
	$(CC) -O2 -Wall -g $< -o $@
59

  
60
# new i386 emulator
61
dyngen: dyngen.c
62
	$(HOST_CC) -O2 -Wall -g $< -o $@
63

  
64
translate-i386.o: translate-i386.c op-i386.h cpu-i386.h
65

  
66
op-i386.h: op-i386.o dyngen
67
	./dyngen -o $@ $<
68

  
69
op-i386.o: op-i386.c opreg_template.h ops_template.h
70
	$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
71

  
48 72
%.o: %.c
49 73
	$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
50 74

  
51 75
clean:
52
	rm -f *.o *~ i386/*.o i386/*~ gemu hello test1 test2 TAGS
53

  
54
hello: hello.c
55
	$(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
76
	rm -f *.o *~ i386/*.o i386/*~ gemu TAGS
56 77

  
57
test1: test1.c
58
	$(CC) $(CFLAGS) -static $(LDFLAGS) -o $@ $<
78
# various test targets
79
test speed: gemu
80
	make -C tests $@
59 81

  
60
test2: test2.c
61
	$(CC) $(CFLAGS) -static $(LDFLAGS) -o $@ $<
82
TAGS: 
83
	etags *.[ch] i386/*.[ch]
62 84

  
63 85
ifneq ($(wildcard .depend),)
64 86
include .depend
b/TODO
1
- swap all elf paramters
1
- tests
2
- signals
3
- threads
2 4
- fix printf for doubles (fp87.c bug ?)
5
- make it self runnable (use same trick as ld.so : include its own relocator and libc)
b/cpu-i386.h
1
#ifndef CPU_I386_H
2
#define CPU_I386_H
3

  
4
#define R_EAX 0
5
#define R_ECX 1
6
#define R_EDX 2
7
#define R_EBX 3
8
#define R_ESP 4
9
#define R_EBP 5
10
#define R_ESI 6
11
#define R_EDI 7
12

  
13
#define R_AL 0
14
#define R_CL 1
15
#define R_DL 2
16
#define R_BL 3
17
#define R_AH 4
18
#define R_CH 5
19
#define R_DH 6
20
#define R_BH 7
21

  
22
#define R_ES 0
23
#define R_CS 1
24
#define R_SS 2
25
#define R_DS 3
26
#define R_FS 4
27
#define R_GS 5
28

  
29
#define CC_C   	0x0001
30
#define CC_P 	0x0004
31
#define CC_A	0x0010
32
#define CC_Z	0x0040
33
#define CC_S    0x0080
34
#define CC_O    0x0800
35

  
36
#define TRAP_FLAG		0x0100
37
#define INTERRUPT_FLAG		0x0200
38
#define DIRECTION_FLAG		0x0400
39
#define IOPL_FLAG_MASK		0x3000
40
#define NESTED_FLAG		0x4000
41
#define BYTE_FL			0x8000	/* Intel reserved! */
42
#define RF_FLAG			0x10000
43
#define VM_FLAG			0x20000
44
/* AC				0x40000 */
45

  
46
enum {
47
    CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
48
    CC_OP_EFLAGS,  /* all cc are explicitely computed, CC_SRC = flags */
49
    CC_OP_MUL, /* modify all flags, C, O = (CC_SRC != 0) */
50

  
51
    CC_OP_ADDB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
52
    CC_OP_ADDW,
53
    CC_OP_ADDL,
54

  
55
    CC_OP_SUBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
56
    CC_OP_SUBW,
57
    CC_OP_SUBL,
58

  
59
    CC_OP_LOGICB, /* modify all flags, CC_DST = res */
60
    CC_OP_LOGICW,
61
    CC_OP_LOGICL,
62

  
63
    CC_OP_INCB, /* modify all flags except, CC_DST = res */
64
    CC_OP_INCW,
65
    CC_OP_INCL,
66

  
67
    CC_OP_DECB, /* modify all flags except, CC_DST = res */
68
    CC_OP_DECW,
69
    CC_OP_DECL,
70

  
71
    CC_OP_SHLB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */
72
    CC_OP_SHLW,
73
    CC_OP_SHLL,
74

  
75
    CC_OP_NB,
76
};
77

  
78
typedef struct CPU86State {
79
    /* standard registers */
80
    uint32_t regs[8];
81
    uint32_t pc; /* cs_case + eip value */
82

  
83
    /* eflags handling */
84
    uint32_t eflags;
85
    uint32_t cc_src;
86
    uint32_t cc_dst;
87
    uint32_t cc_op;
88
    int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
89
    
90
    /* segments */
91
    uint8_t *segs_base[6];
92
    uint32_t segs[6];
93

  
94
    /* emulator internal variables */
95
    uint32_t t0; /* temporary t0 storage */
96
    uint32_t t1; /* temporary t1 storage */
97
    uint32_t a0; /* temporary a0 storage (address) */
98
} CPU86State;
99

  
100
static inline int ldub(void *ptr)
101
{
102
    return *(uint8_t *)ptr;
103
}
104

  
105
static inline int ldsb(void *ptr)
106
{
107
    return *(int8_t *)ptr;
108
}
109

  
110
static inline int lduw(void *ptr)
111
{
112
    return *(uint16_t *)ptr;
113
}
114

  
115
static inline int ldsw(void *ptr)
116
{
117
    return *(int16_t *)ptr;
118
}
119

  
120
static inline int ldl(void *ptr)
121
{
122
    return *(uint32_t *)ptr;
123
}
124

  
125

  
126
static inline void stb(void *ptr, int v)
127
{
128
    *(uint8_t *)ptr = v;
129
}
130

  
131
static inline void stw(void *ptr, int v)
132
{
133
    *(uint16_t *)ptr = v;
134
}
135

  
136
static inline void stl(void *ptr, int v)
137
{
138
    *(uint32_t *)ptr = v;
139
}
140

  
141
void port_outb(int addr, int val);
142
void port_outw(int addr, int val);
143
void port_outl(int addr, int val);
144
int port_inb(int addr);
145
int port_inw(int addr);
146
int port_inl(int addr);
147

  
148
#endif /* CPU_I386_H */
b/dyngen.c
1
#include <stdlib.h>
2
#include <stdio.h>
3
#include <stdarg.h>
4
#include <inttypes.h>
5
#include <elf.h>
6
#include <unistd.h>
7
#include <fcntl.h>
8

  
9
#include "thunk.h"
10

  
11
/* all dynamically generated functions begin with this code */
12
#define OP_PREFIX "op"
13

  
14
int elf_must_swap(Elf32_Ehdr *h)
15
{
16
  union {
17
      uint32_t i;
18
      uint8_t b[4];
19
  } swaptest;
20

  
21
  swaptest.i = 1;
22
  return (h->e_ident[EI_DATA] == ELFDATA2MSB) != 
23
      (swaptest.b[0] == 0);
24
}
25
  
26
void swab16s(uint16_t *p)
27
{
28
    *p = bswap16(*p);
29
}
30

  
31
void swab32s(uint32_t *p)
32
{
33
    *p = bswap32(*p);
34
}
35

  
36
void swab64s(uint32_t *p)
37
{
38
    *p = bswap64(*p);
39
}
40

  
41
void elf_swap_ehdr(Elf32_Ehdr *h)
42
{
43
    swab16s(&h->e_type);			/* Object file type */
44
    swab16s(&h->	e_machine);		/* Architecture */
45
    swab32s(&h->	e_version);		/* Object file version */
46
    swab32s(&h->	e_entry);		/* Entry point virtual address */
47
    swab32s(&h->	e_phoff);		/* Program header table file offset */
48
    swab32s(&h->	e_shoff);		/* Section header table file offset */
49
    swab32s(&h->	e_flags);		/* Processor-specific flags */
50
    swab16s(&h->	e_ehsize);		/* ELF header size in bytes */
51
    swab16s(&h->	e_phentsize);		/* Program header table entry size */
52
    swab16s(&h->	e_phnum);		/* Program header table entry count */
53
    swab16s(&h->	e_shentsize);		/* Section header table entry size */
54
    swab16s(&h->	e_shnum);		/* Section header table entry count */
55
    swab16s(&h->	e_shstrndx);		/* Section header string table index */
56
}
57

  
58
void elf_swap_shdr(Elf32_Shdr *h)
59
{
60
  swab32s(&h->	sh_name);		/* Section name (string tbl index) */
61
  swab32s(&h->	sh_type);		/* Section type */
62
  swab32s(&h->	sh_flags);		/* Section flags */
63
  swab32s(&h->	sh_addr);		/* Section virtual addr at execution */
64
  swab32s(&h->	sh_offset);		/* Section file offset */
65
  swab32s(&h->	sh_size);		/* Section size in bytes */
66
  swab32s(&h->	sh_link);		/* Link to another section */
67
  swab32s(&h->	sh_info);		/* Additional section information */
68
  swab32s(&h->	sh_addralign);		/* Section alignment */
69
  swab32s(&h->	sh_entsize);		/* Entry size if section holds table */
70
}
71

  
72
void elf_swap_phdr(Elf32_Phdr *h)
73
{
74
    swab32s(&h->p_type);			/* Segment type */
75
    swab32s(&h->p_offset);		/* Segment file offset */
76
    swab32s(&h->p_vaddr);		/* Segment virtual address */
77
    swab32s(&h->p_paddr);		/* Segment physical address */
78
    swab32s(&h->p_filesz);		/* Segment size in file */
79
    swab32s(&h->p_memsz);		/* Segment size in memory */
80
    swab32s(&h->p_flags);		/* Segment flags */
81
    swab32s(&h->p_align);		/* Segment alignment */
82
}
83

  
84
int do_swap;
85
int e_machine;
86

  
87
uint16_t get16(uint16_t *p)
88
{
89
    uint16_t val;
90
    val = *p;
91
    if (do_swap)
92
        val = bswap16(val);
93
    return val;
94
}
95

  
96
uint32_t get32(uint32_t *p)
97
{
98
    uint32_t val;
99
    val = *p;
100
    if (do_swap)
101
        val = bswap32(val);
102
    return val;
103
}
104

  
105
void put16(uint16_t *p, uint16_t val)
106
{
107
    if (do_swap)
108
        val = bswap16(val);
109
    *p = val;
110
}
111

  
112
void put32(uint32_t *p, uint32_t val)
113
{
114
    if (do_swap)
115
        val = bswap32(val);
116
    *p = val;
117
}
118

  
119
void __attribute__((noreturn)) error(const char *fmt, ...)
120
{
121
    va_list ap;
122
    va_start(ap, fmt);
123
    fprintf(stderr, "dyngen: ");
124
    vfprintf(stderr, fmt, ap);
125
    fprintf(stderr, "\n");
126
    va_end(ap);
127
    exit(1);
128
}
129

  
130

  
131
Elf32_Shdr *find_elf_section(Elf32_Shdr *shdr, int shnum, const char *shstr, 
132
                             const char *name)
133
{
134
    int i;
135
    const char *shname;
136
    Elf32_Shdr *sec;
137

  
138
    for(i = 0; i < shnum; i++) {
139
        sec = &shdr[i];
140
        if (!sec->sh_name)
141
            continue;
142
        shname = shstr + sec->sh_name;
143
        if (!strcmp(shname, name))
144
            return sec;
145
    }
146
    return NULL;
147
}
148

  
149
void *load_data(int fd, long offset, unsigned int size)
150
{
151
    char *data;
152

  
153
    data = malloc(size);
154
    if (!data)
155
        return NULL;
156
    lseek(fd, offset, SEEK_SET);
157
    if (read(fd, data, size) != size) {
158
        free(data);
159
        return NULL;
160
    }
161
    return data;
162
}
163

  
164
int strstart(const char *str, const char *val, const char **ptr)
165
{
166
    const char *p, *q;
167
    p = str;
168
    q = val;
169
    while (*q != '\0') {
170
        if (*p != *q)
171
            return 0;
172
        p++;
173
        q++;
174
    }
175
    if (ptr)
176
        *ptr = p;
177
    return 1;
178
}
179

  
180
#define MAX_ARGS 3
181

  
182
/* generate op code */
183
void gen_code(const char *name, unsigned long offset, unsigned long size, 
184
              FILE *outfile, uint8_t *text, void *relocs, int nb_relocs, int reloc_sh_type,
185
              Elf32_Sym *symtab, char *strtab)
186
{
187
    int copy_size = 0;
188
    uint8_t *p_start, *p_end;
189
    int nb_args, i;
190
    uint8_t args_present[MAX_ARGS];
191
    const char *sym_name, *p;
192

  
193
    /* compute exact size excluding return instruction */
194
    p_start = text + offset;
195
    p_end = p_start + size;
196
    switch(e_machine) {
197
    case EM_386:
198
        {
199
            uint8_t *p;
200
            p = p_end - 1;
201
            /* find ret */
202
            while (p > p_start && *p != 0xc3)
203
                p--;
204
            /* skip double ret */
205
            if (p > p_start && p[-1] == 0xc3)
206
                p--;
207
            if (p == p_start)
208
                error("empty code for %s", name);
209
            copy_size = p - p_start;
210
        }
211
        break;
212
    case EM_PPC:
213
        {
214
            uint8_t *p;
215
            p = (void *)(p_end - 4);
216
            /* find ret */
217
            while (p > p_start && get32((uint32_t *)p) != 0x4e800020)
218
                p -= 4;
219
            /* skip double ret */
220
            if (p > p_start && get32((uint32_t *)(p - 4)) == 0x4e800020)
221
                p -= 4;
222
            if (p == p_start)
223
                error("empty code for %s", name);
224
            copy_size = p - p_start;
225
        }
226
        break;
227
    default:
228
        error("unsupported CPU (%d)", e_machine);
229
    }
230

  
231
    /* compute the number of arguments by looking at the relocations */
232
    for(i = 0;i < MAX_ARGS; i++)
233
        args_present[i] = 0;
234

  
235
    if (reloc_sh_type == SHT_REL) {
236
        Elf32_Rel *rel;
237
        int n;
238
        for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
239
            if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
240
                sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
241
                if (strstart(sym_name, "__op_param", &p)) {
242
                    n = strtoul(p, NULL, 10);
243
                    if (n >= MAX_ARGS)
244
                        error("too many arguments in %s", name);
245
                    args_present[n - 1] = 1;
246
                }
247
            }
248
        }
249
    } else {
250
        Elf32_Rela *rel;
251
        int n;
252
        for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
253
            if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
254
                sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
255
                if (strstart(sym_name, "__op_param", &p)) {
256
                    n = strtoul(p, NULL, 10);
257
                    if (n >= MAX_ARGS)
258
                        error("too many arguments in %s", name);
259
                    args_present[n - 1] = 1;
260
                }
261
            }
262
        }
263
    }
264
    
265
    nb_args = 0;
266
    while (nb_args < MAX_ARGS && args_present[nb_args])
267
        nb_args++;
268
    for(i = nb_args; i < MAX_ARGS; i++) {
269
        if (args_present[i])
270
            error("inconsistent argument numbering in %s", name);
271
    }
272

  
273
    /* output C code */
274
    fprintf(outfile, "extern void %s();\n", name);
275
    fprintf(outfile, "static inline void gen_%s(", name);
276
    if (nb_args == 0) {
277
        fprintf(outfile, "void");
278
    } else {
279
        for(i = 0; i < nb_args; i++) {
280
            if (i != 0)
281
                fprintf(outfile, ", ");
282
            fprintf(outfile, "long param%d", i + 1);
283
        }
284
    }
285
    fprintf(outfile, ")\n");
286
    fprintf(outfile, "{\n");
287
    fprintf(outfile, "    memcpy(gen_code_ptr, &%s, %d);\n", name, copy_size);
288
    
289
    /* patch relocations */
290
    switch(e_machine) {
291
    case EM_386:
292
        {
293
            Elf32_Rel *rel;
294
            char name[256];
295
            int type;
296
            long addend;
297
            for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
298
                if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
299
                    sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
300
                    if (strstart(sym_name, "__op_param", &p)) {
301
                        snprintf(name, sizeof(name), "param%s", p);
302
                    } else {
303
                        snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
304
                    }
305
                    type = ELF32_R_TYPE(rel->r_info);
306
                    addend = get32((uint32_t *)(text + rel->r_offset));
307
                    switch(type) {
308
                    case R_386_32:
309
                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n", 
310
                                rel->r_offset - offset, name, addend);
311
                        break;
312
                    case R_386_PC32:
313
                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %ld) = %s - (long)(gen_code_ptr + %ld) + %ld;\n", 
314
                                rel->r_offset - offset, name, rel->r_offset - offset, addend);
315
                        break;
316
                    default:
317
                        error("unsupported i386 relocation (%d)", type);
318
                    }
319
                }
320
            }
321
        }
322
        break;
323
    default:
324
        error("unsupported CPU for relocations (%d)", e_machine);
325
    }
326

  
327

  
328
    fprintf(outfile, "    gen_code_ptr += %d;\n", copy_size);
329
    fprintf(outfile, "}\n\n");
330
}
331

  
332
/* load an elf object file */
333
int load_elf(const char *filename, FILE *outfile)
334
{
335
    int fd;
336
    Elf32_Ehdr ehdr;
337
    Elf32_Shdr *sec, *shdr, *symtab_sec, *strtab_sec, *text_sec;
338
    int i, j, nb_syms;
339
    Elf32_Sym *symtab, *sym;
340
    const char *cpu_name;
341
    char *shstr, *strtab;
342
    uint8_t *text;
343
    void *relocs;
344
    int nb_relocs, reloc_sh_type;
345
    
346
    fd = open(filename, O_RDONLY);
347
    if (fd < 0) 
348
        error("can't open file '%s'", filename);
349
    
350
    /* Read ELF header.  */
351
    if (read(fd, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
352
        error("unable to read file header");
353

  
354
    /* Check ELF identification.  */
355
    if (ehdr.e_ident[EI_MAG0] != ELFMAG0
356
     || ehdr.e_ident[EI_MAG1] != ELFMAG1
357
     || ehdr.e_ident[EI_MAG2] != ELFMAG2
358
     || ehdr.e_ident[EI_MAG3] != ELFMAG3
359
     || ehdr.e_ident[EI_CLASS] != ELFCLASS32
360
     || ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
361
        error("bad ELF header");
362
    }
363

  
364
    do_swap = elf_must_swap(&ehdr);
365
    if (do_swap)
366
        elf_swap_ehdr(&ehdr);
367
    if (ehdr.e_type != ET_REL)
368
        error("ELF object file expected");
369
    if (ehdr.e_version != EV_CURRENT)
370
        error("Invalid ELF version");
371
    e_machine = ehdr.e_machine;
372

  
373
    /* read section headers */
374
    shdr = load_data(fd, ehdr.e_shoff, ehdr.e_shnum * sizeof(Elf32_Shdr));
375
    if (do_swap) {
376
        for(i = 0; i < ehdr.e_shnum; i++) {
377
            elf_swap_shdr(&shdr[i]);
378
        }
379
    }
380

  
381
    sec = &shdr[ehdr.e_shstrndx];
382
    shstr = load_data(fd, sec->sh_offset, sec->sh_size);
383

  
384
    /* text section */
385

  
386
    text_sec = find_elf_section(shdr, ehdr.e_shnum, shstr, ".text");
387
    if (!text_sec)
388
        error("could not find .text section");
389
    text = load_data(fd, text_sec->sh_offset, text_sec->sh_size);
390

  
391
    /* find text relocations, if any */
392
    nb_relocs = 0;
393
    relocs = NULL;
394
    reloc_sh_type = 0;
395
    for(i = 0; i < ehdr.e_shnum; i++) {
396
        sec = &shdr[i];
397
        if ((sec->sh_type == SHT_REL || sec->sh_type == SHT_RELA) &&
398
            sec->sh_info == (text_sec - shdr)) {
399
            reloc_sh_type = sec->sh_type;
400
            relocs = load_data(fd, sec->sh_offset, sec->sh_size);
401
            nb_relocs = sec->sh_size / sec->sh_entsize;
402
            if (do_swap) {
403
                if (sec->sh_type == SHT_REL) {
404
                    Elf32_Rel *rel = relocs;
405
                    for(j = 0, rel = relocs; j < nb_relocs; j++, rel++) {
406
                        swab32s(&rel->r_offset);
407
                        swab32s(&rel->r_info);
408
                    }
409
                } else {
410
                    Elf32_Rela *rel = relocs;
411
                    for(j = 0, rel = relocs; j < nb_relocs; j++, rel++) {
412
                        swab32s(&rel->r_offset);
413
                        swab32s(&rel->r_info);
414
                        swab32s(&rel->r_addend);
415
                    }
416
                }
417
            }
418
            break;
419
        }
420
    }
421

  
422
    symtab_sec = find_elf_section(shdr, ehdr.e_shnum, shstr, ".symtab");
423
    if (!symtab_sec)
424
        error("could not find .symtab section");
425
    strtab_sec = &shdr[symtab_sec->sh_link];
426

  
427
    symtab = load_data(fd, symtab_sec->sh_offset, symtab_sec->sh_size);
428
    strtab = load_data(fd, strtab_sec->sh_offset, strtab_sec->sh_size);
429
    
430
    nb_syms = symtab_sec->sh_size / sizeof(Elf32_Sym);
431
    if (do_swap) {
432
        for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
433
            swab32s(&sym->st_name);
434
            swab32s(&sym->st_value);
435
            swab32s(&sym->st_size);
436
            swab16s(&sym->st_shndx);
437
        }
438
    }
439

  
440
    switch(e_machine) {
441
    case EM_386:
442
        cpu_name = "i386";
443
        break;
444
    case EM_PPC:
445
        cpu_name = "ppc";
446
        break;
447
    case EM_MIPS:
448
        cpu_name = "mips";
449
        break;
450
    case EM_ARM:
451
        cpu_name = "arm";
452
        break;
453
    case EM_SPARC:
454
        cpu_name = "sparc";
455
        break;
456
    default:
457
        error("unsupported CPU (e_machine=%d)", e_machine);
458
    }
459

  
460
    fprintf(outfile, "#include \"gen-%s.h\"\n\n", cpu_name);
461

  
462
    for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
463
        const char *name;
464
        name = strtab + sym->st_name;
465
        if (strstart(name, "op_", NULL) ||
466
            strstart(name, "op1_", NULL) ||
467
            strstart(name, "op2_", NULL) ||
468
            strstart(name, "op3_", NULL)) {
469
#if 0
470
            printf("%4d: %s pos=0x%08x len=%d\n", 
471
                   i, name, sym->st_value, sym->st_size);
472
#endif
473
            if (sym->st_shndx != (text_sec - shdr))
474
                error("invalid section for opcode (0x%x)", sym->st_shndx);
475
            gen_code(name, sym->st_value, sym->st_size, outfile, 
476
                     text, relocs, nb_relocs, reloc_sh_type, symtab, strtab);
477
        }
478
    }
479

  
480
    close(fd);
481
    return 0;
482
}
483

  
484
void usage(void)
485
{
486
    printf("dyngen (c) 2003 Fabrice Bellard\n"
487
           "usage: dyngen [-o outfile] objfile\n"
488
           "Generate a dynamic code generator from an object file\n");
489
    exit(1);
490
}
491

  
492
int main(int argc, char **argv)
493
{
494
    int c;
495
    const char *filename, *outfilename;
496
    FILE *outfile;
497

  
498
    outfilename = "out.c";
499
    for(;;) {
500
        c = getopt(argc, argv, "ho:");
501
        if (c == -1)
502
            break;
503
        switch(c) {
504
        case 'h':
505
            usage();
506
            break;
507
        case 'o':
508
            outfilename = optarg;
509
            break;
510
        }
511
    }
512
    if (optind >= argc)
513
        usage();
514
    filename = argv[optind];
515
    outfile = fopen(outfilename, "w");
516
    if (!outfile)
517
        error("could not open '%s'", outfilename);
518
    load_elf(filename, outfile);
519
    fclose(outfile);
520
    return 0;
521
}
b/gen-i386.h
1
static inline void gen_start(void)
2
{
3
}
4

  
5
static inline void gen_end(void)
6
{
7
    *gen_code_ptr++ = 0xc3; /* ret */
8
}
b/linux-user/main.c
191 191
}
192 192

  
193 193
/***********************************************************/
194
/* new CPU core */
195

  
196
void port_outb(int addr, int val)
197
{
198
    fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);
199
}
200

  
201
void port_outw(int addr, int val)
202
{
203
    fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);
204
}
205

  
206
void port_outl(int addr, int val)
207
{
208
    fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
209
}
210

  
211
int port_inb(int addr)
212
{
213
    fprintf(stderr, "inb: port=0x%04x\n", addr);
214
    return 0;
215
}
216

  
217
int port_inw(int addr)
218
{
219
    fprintf(stderr, "inw: port=0x%04x\n", addr);
220
    return 0;
221
}
222

  
223
int port_inl(int addr)
224
{
225
    fprintf(stderr, "inl: port=0x%04x\n", addr);
226
    return 0;
227
}
228

  
194 229

  
195 230
/* XXX: currently we use LDT entries */
196 231
#define __USER_CS	(0x23|4)
......
270 305
    LDT[__USER_DS >> 3].dwSelLimit = 0xfffff;
271 306
    LDT[__USER_DS >> 3].lpSelBase = NULL;
272 307
    init_npu();
308
    build_decode_tables();
273 309

  
274 310
    for(;;) {
275 311
        int err;
b/op-i386.c
8 8
typedef signed int int32_t;
9 9
typedef signed long long int64_t;
10 10

  
11
#define NULL 0
12

  
11 13
#ifdef __i386__
12 14
register int T0 asm("esi");
13 15
register int T1 asm("ebx");
......
74 76
#include "cpu-i386.h"
75 77

  
76 78
typedef struct CCTable {
77
    int (*compute_c)(void);  /* return the C flag */
78
    int (*compute_z)(void);  /* return the Z flag */
79
    int (*compute_s)(void);  /* return the S flag */
80
    int (*compute_o)(void);  /* return the O flag */
81 79
    int (*compute_all)(void); /* return all the flags */
80
    int (*compute_c)(void);  /* return the C flag */
82 81
} CCTable;
83 82

  
83
extern CCTable cc_table[];
84

  
84 85
uint8_t parity_table[256] = {
85 86
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
86 87
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
......
116 117
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
117 118
};
118 119

  
119
static int compute_eflags_all(void)
120
{
121
    return CC_SRC;
122
}
123

  
124
static int compute_eflags_addb(void)
125
{
126
    int cf, pf, af, zf, sf, of;
127
    int src1, src2;
128
    src1 = CC_SRC;
129
    src2 = CC_DST - CC_SRC;
130
    cf = (uint8_t)CC_DST < (uint8_t)src1;
131
    pf = parity_table[(uint8_t)CC_DST];
132
    af = (CC_DST ^ src1 ^ src2) & 0x10;
133
    zf = ((uint8_t)CC_DST != 0) << 6;
134
    sf = CC_DST & 0x80;
135
    of = ((src1 ^ src2 ^ -1) & (src1 ^ CC_DST) & 0x80) << 4;
136
    return cf | pf | af | zf | sf | of;
137
}
138

  
139
static int compute_eflags_subb(void)
140
{
141
    int cf, pf, af, zf, sf, of;
142
    int src1, src2;
143
    src1 = CC_SRC;
144
    src2 = CC_SRC - CC_DST;
145
    cf = (uint8_t)src1 < (uint8_t)src2;
146
    pf = parity_table[(uint8_t)CC_DST];
147
    af = (CC_DST ^ src1 ^ src2) & 0x10;
148
    zf = ((uint8_t)CC_DST != 0) << 6;
149
    sf = CC_DST & 0x80;
150
    of = ((src1 ^ src2 ^ -1) & (src1 ^ CC_DST) & 0x80) << 4;
151
    return cf | pf | af | zf | sf | of;
152
}
153

  
154
static int compute_eflags_logicb(void)
155
{
156
    cf = 0;
157
    pf = parity_table[(uint8_t)CC_DST];
158
    af = 0;
159
    zf = ((uint8_t)CC_DST != 0) << 6;
160
    sf = CC_DST & 0x80;
161
    of = 0;
162
    return cf | pf | af | zf | sf | of;
163
}
164

  
165
static int compute_eflags_incb(void)
166
{
167
    int cf, pf, af, zf, sf, of;
168
    int src2;
169
    src1 = CC_DST - 1;
170
    src2 = 1;
171
    cf = CC_SRC;
172
    pf = parity_table[(uint8_t)CC_DST];
173
    af = (CC_DST ^ src1 ^ src2) & 0x10;
174
    zf = ((uint8_t)CC_DST != 0) << 6;
175
    sf = CC_DST & 0x80;
176
    of = ((src1 ^ src2 ^ -1) & (src1 ^ CC_DST) & 0x80) << 4;
177
    return cf | pf | af | zf | sf | of;
178
}
179

  
180
static int compute_eflags_decb(void)
181
{
182
    int cf, pf, af, zf, sf, of;
183
    int src1, src2;
184
    src1 = CC_DST + 1;
185
    src2 = 1;
186
    cf = (uint8_t)src1 < (uint8_t)src2;
187
    pf = parity_table[(uint8_t)CC_DST];
188
    af = (CC_DST ^ src1 ^ src2) & 0x10;
189
    zf = ((uint8_t)CC_DST != 0) << 6;
190
    sf = CC_DST & 0x80;
191
    of = ((src1 ^ src2 ^ -1) & (src1 ^ CC_DST) & 0x80) << 4;
192
    return cf | pf | af | zf | sf | of;
193
}
194

  
195
static int compute_eflags_shlb(void)
196
{
197
    cf = CC_SRC;
198
    pf = parity_table[(uint8_t)CC_DST];
199
    af = 0; /* undefined */
200
    zf = ((uint8_t)CC_DST != 0) << 6;
201
    sf = CC_DST & 0x80;
202
    of = 0; /* undefined */
203
    return cf | pf | af | zf | sf | of;
204
}
120
/* modulo 17 table */
121
const uint8_t rclw_table[32] = {
122
    0, 1, 2, 3, 4, 5, 6, 7, 
123
    8, 9,10,11,12,13,14,15,
124
   16, 0, 1, 2, 3, 4, 5, 6,
125
    7, 8, 9,10,11,12,13,14,
126
};
205 127

  
206
static int compute_eflags_shrb(void)
207
{
208
    cf = CC_SRC & 1;
209
    pf = parity_table[(uint8_t)CC_DST];
210
    af = 0; /* undefined */
211
    zf = ((uint8_t)CC_DST != 0) << 6;
212
    sf = CC_DST & 0x80;
213
    of = sf << 4;
214
    return cf | pf | af | zf | sf | of;
215
}
128
/* modulo 9 table */
129
const uint8_t rclb_table[32] = {
130
    0, 1, 2, 3, 4, 5, 6, 7, 
131
    8, 0, 1, 2, 3, 4, 5, 6,
132
    7, 8, 0, 1, 2, 3, 4, 5, 
133
    6, 7, 8, 0, 1, 2, 3, 4,
134
};
216 135

  
217
static int compute_eflags_mul(void)
136
/* n must be a constant to be efficient */
137
static inline int lshift(int x, int n)
218 138
{
219
    cf = (CC_SRC != 0);
220
    pf = 0; /* undefined */
221
    af = 0; /* undefined */
222
    zf = 0; /* undefined */
223
    sf = 0; /* undefined */
224
    of = cf << 11;
225
    return cf | pf | af | zf | sf | of;
139
    if (n >= 0)
140
        return x << n;
141
    else
142
        return x >> (-n);
226 143
}
227
    
228
CTable cc_table[CC_OP_NB] = {
229
    [CC_OP_DYNAMIC] = { NULL, NULL, NULL },
230
    [CC_OP_EFLAGS] = { NULL, NULL, NULL },
231
    
232
};
233 144

  
234 145
/* we define the various pieces of code used by the JIT */
235 146

  
......
365 276
    CC_DST = T0 & T1;
366 277
}
367 278

  
368
/* shifts */
369

  
370
void OPPROTO op_roll_T0_T1_cc(void)
371
{
372
    int count;
373
    count = T1 & 0x1f;
374
    if (count) {
375
        CC_SRC = T0;
376
        T0 = (T0 << count) | (T0 >> (32 - count));
377
        CC_DST = T0;
378
        CC_OP = CC_OP_ROLL;
379
    }
380
}
381

  
382
void OPPROTO op_rolw_T0_T1_cc(void)
383
{
384
    int count;
385
    count = T1 & 0xf;
386
    if (count) {
387
        T0 = T0 & 0xffff;
388
        CC_SRC = T0;
389
        T0 = (T0 << count) | (T0 >> (16 - count));
390
        CC_DST = T0;
391
        CC_OP = CC_OP_ROLW;
392
    }
393
}
394

  
395
void OPPROTO op_rolb_T0_T1_cc(void)
396
{
397
    int count;
398
    count = T1 & 0x7;
399
    if (count) {
400
        T0 = T0 & 0xff;
401
        CC_SRC = T0;
402
        T0 = (T0 << count) | (T0 >> (8 - count));
403
        CC_DST = T0;
404
        CC_OP = CC_OP_ROLB;
405
    }
406
}
407

  
408
void OPPROTO op_rorl_T0_T1_cc(void)
409
{
410
    int count;
411
    count = T1 & 0x1f;
412
    if (count) {
413
        CC_SRC = T0;
414
        T0 = (T0 >> count) | (T0 << (32 - count));
415
        CC_DST = T0;
416
        CC_OP = CC_OP_RORB;
417
    }
418
}
419

  
420
void OPPROTO op_rorw_T0_T1_cc(void)
421
{
422
    int count;
423
    count = T1 & 0xf;
424
    if (count) {
425
        CC_SRC = T0;
426
        T0 = (T0 >> count) | (T0 << (16 - count));
427
        CC_DST = T0;
428
        CC_OP = CC_OP_RORW;
429
    }
430
}
431

  
432
void OPPROTO op_rorb_T0_T1_cc(void)
433
{
434
    int count;
435
    count = T1 & 0x7;
436
    if (count) {
437
        CC_SRC = T0;
438
        T0 = (T0 >> count) | (T0 << (8 - count));
439
        CC_DST = T0;
440
        CC_OP = CC_OP_RORL;
441
    }
442
}
443

  
444
/* modulo 17 table */
445
const uint8_t rclw_table[32] = {
446
    0, 1, 2, 3, 4, 5, 6, 7, 
447
    8, 9,10,11,12,13,14,15,
448
   16, 0, 1, 2, 3, 4, 5, 6,
449
    7, 8, 9,10,11,12,13,14,
450
};
451

  
452
/* modulo 9 table */
453
const uint8_t rclb_table[32] = {
454
    0, 1, 2, 3, 4, 5, 6, 7, 
455
    8, 0, 1, 2, 3, 4, 5, 6,
456
    7, 8, 0, 1, 2, 3, 4, 5, 
457
    6, 7, 8, 0, 1, 2, 3, 4,
458
};
459

  
460
void helper_rcll_T0_T1_cc(void)
461
{
462
    int count, res;
463

  
464
    count = T1 & 0x1f;
465
    if (count) {
466
        CC_SRC = T0;
467
        res = (T0 << count) | (cc_table[CC_OP].compute_c() << (count - 1));
468
        if (count > 1)
469
            res |= T0 >> (33 - count);
470
        T0 = res;
471
        CC_DST = T0 ^ CC_SRC;    /* O is in bit 31 */
472
        CC_SRC >>= (32 - count); /* CC is in bit 0 */
473
        CC_OP = CC_OP_RCLL;
474
    }
475
}
476

  
477
void OPPROTO op_rcll_T0_T1_cc(void)
478
{
479
    helper_rcll_T0_T1_cc();
480
}
481

  
482
void OPPROTO op_rclw_T0_T1_cc(void)
483
{
484
    int count;
485
    count = rclw_table[T1 & 0x1f];
486
    if (count) {
487
        T0 = T0 & 0xffff;
488
        CC_SRC = T0;
489
        T0 = (T0 << count) | (cc_table[CC_OP].compute_c() << (count - 1)) |
490
            (T0 >> (17 - count));
491
        CC_DST = T0 ^ CC_SRC;
492
        CC_SRC >>= (16 - count);
493
        CC_OP = CC_OP_RCLW;
494
    }
495
}
496

  
497
void OPPROTO op_rclb_T0_T1_cc(void)
498
{
499
    int count;
500
    count = rclb_table[T1 & 0x1f];
501
    if (count) {
502
        T0 = T0 & 0xff;
503
        CC_SRC = T0;
504
        T0 = (T0 << count) | (cc_table[CC_OP].compute_c() << (count - 1)) |
505
            (T0 >> (9 - count));
506
        CC_DST = T0 ^ CC_SRC;
507
        CC_SRC >>= (8 - count);
508
        CC_OP = CC_OP_RCLB;
509
    }
510
}
511

  
512
void OPPROTO op_rcrl_T0_T1_cc(void)
513
{
514
    int count, res;
515
    count = T1 & 0x1f;
516
    if (count) {
517
        CC_SRC = T0;
518
        res = (T0 >> count) | (cc_table[CC_OP].compute_c() << (32 - count));
519
        if (count > 1)
520
            res |= T0 << (33 - count);
521
        T0 = res;
522
        CC_DST = T0 ^ CC_SRC;
523
        CC_SRC >>= (count - 1);
524
        CC_OP = CC_OP_RCLL;
525
    }
526
}
527

  
528
void OPPROTO op_rcrw_T0_T1_cc(void)
529
{
530
    int count;
531
    count = rclw_table[T1 & 0x1f];
532
    if (count) {
533
        T0 = T0 & 0xffff;
534
        CC_SRC = T0;
535
        T0 = (T0 >> count) | (cc_table[CC_OP].compute_c() << (16 - count)) |
536
            (T0 << (17 - count));
537
        CC_DST = T0 ^ CC_SRC;
538
        CC_SRC >>= (count - 1);
539
        CC_OP = CC_OP_RCLW;
540
    }
541
}
542

  
543
void OPPROTO op_rcrb_T0_T1_cc(void)
544
{
545
    int count;
546
    count = rclb_table[T1 & 0x1f];
547
    if (count) {
548
        T0 = T0 & 0xff;
549
        CC_SRC = T0;
550
        T0 = (T0 >> count) | (cc_table[CC_OP].compute_c() << (8 - count)) |
551
            (T0 << (9 - count));
552
        CC_DST = T0 ^ CC_SRC;
553
        CC_SRC >>= (count - 1);
554
        CC_OP = CC_OP_RCLB;
555
    }
556
}
557

  
558
void OPPROTO op_shll_T0_T1_cc(void)
559
{
560
    int count;
561
    count = T1 & 0x1f;
562
    if (count == 1) {
563
        CC_SRC = T0;
564
        T0 = T0 << 1;
565
        CC_DST = T0;
566
        CC_OP = CC_OP_ADDL;
567
    } else if (count) {
568
        CC_SRC = T0 >> (32 - count);
569
        T0 = T0 << count;
570
        CC_DST = T0;
571
        CC_OP = CC_OP_SHLL;
572
    }
573
}
574

  
575
void OPPROTO op_shlw_T0_T1_cc(void)
576
{
577
    int count;
578
    count = T1 & 0x1f;
579
    if (count == 1) {
580
        CC_SRC = T0;
581
        T0 = T0 << 1;
582
        CC_DST = T0;
583
        CC_OP = CC_OP_ADDW;
584
    } else if (count) {
585
        CC_SRC = T0 >> (16 - count);
586
        T0 = T0 << count;
587
        CC_DST = T0;
588
        CC_OP = CC_OP_SHLW;
589
    }
590
}
591

  
592
void OPPROTO op_shlb_T0_T1_cc(void)
593
{
594
    int count;
595
    count = T1 & 0x1f;
596
    if (count == 1) {
597
        CC_SRC = T0;
598
        T0 = T0 << 1;
599
        CC_DST = T0;
600
        CC_OP = CC_OP_ADDB;
601
    } else if (count) {
602
        CC_SRC = T0 >> (8 - count);
603
        T0 = T0 << count;
604
        CC_DST = T0;
605
        CC_OP = CC_OP_SHLB;
606
    }
607
}
608

  
609
void OPPROTO op_shrl_T0_T1_cc(void)
610
{
611
    int count;
612
    count = T1 & 0x1f;
613
    if (count == 1) {
614
        CC_SRC = T0;
615
        T0 = T0 >> 1;
616
        CC_DST = T0;
617
        CC_OP = CC_OP_SHRL;
618
    } else if (count) {
619
        CC_SRC = T0 >> (count - 1);
620
        T0 = T0 >> count;
621
        CC_DST = T0;
622
        CC_OP = CC_OP_SHLL;
623
    }
624
}
625

  
626
void OPPROTO op_shrw_T0_T1_cc(void)
627
{
628
    int count;
629
    count = T1 & 0x1f;
630
    if (count == 1) {
631
        T0 = T0 & 0xffff;
632
        CC_SRC = T0;
633
        T0 = T0 >> 1;
634
        CC_DST = T0;
635
        CC_OP = CC_OP_SHRW;
636
    } else if (count) {
637
        T0 = T0 & 0xffff;
638
        CC_SRC = T0 >> (count - 1);
639
        T0 = T0 >> count;
640
        CC_DST = T0;
641
        CC_OP = CC_OP_SHLW;
642
    }
643
}
644

  
645
void OPPROTO op_shrb_T0_T1_cc(void)
646
{
647
    int count;
648
    count = T1 & 0x1f;
649
    if (count == 1) {
650
        T0 = T0 & 0xff;
651
        CC_SRC = T0;
652
        T0 = T0 >> 1;
653
        CC_DST = T0;
654
        CC_OP = CC_OP_SHRB;
655
    } else if (count) {
656
        T0 = T0 & 0xff;
657
        CC_SRC = T0 >> (count - 1);
658
        T0 = T0 >> count;
659
        CC_DST = T0;
660
        CC_OP = CC_OP_SHLB;
661
    }
662
}
663

  
664
void OPPROTO op_sarl_T0_T1_cc(void)
665
{
666
    int count;
667
    count = T1 & 0x1f;
668
    if (count) {
669
        CC_SRC = (int32_t)T0 >> (count - 1);
670
        T0 = (int32_t)T0 >> count;
671
        CC_DST = T0;
672
        CC_OP = CC_OP_SHLL;
673
    }
674
}
675

  
676
void OPPROTO op_sarw_T0_T1_cc(void)
677
{
678
    int count;
679
    count = T1 & 0x1f;
680
    if (count) {
681
        CC_SRC = (int16_t)T0 >> (count - 1);
682
        T0 = (int16_t)T0 >> count;
683
        CC_DST = T0;
684
        CC_OP = CC_OP_SHLW;
685
    }
686
}
687

  
688
void OPPROTO op_sarb_T0_T1_cc(void)
689
{
690
    int count;
691
    count = T1 & 0x1f;
692
    if (count) {
693
        CC_SRC = (int8_t)T0 >> (count - 1);
694
        T0 = (int8_t)T0 >> count;
695
        CC_DST = T0;
696
        CC_OP = CC_OP_SHLB;
697
    }
698
}
699

  
700 279
/* multiply/divide */
701 280
void OPPROTO op_mulb_AL_T0(void)
702 281
{
......
924 503
    stl((uint8_t *)A0, T0);
925 504
}
926 505

  
927
/* flags */
928

  
929
void OPPROTO op_set_cc_op(void)
930
{
931
    CC_OP = PARAM1;
932
}
933

  
934
void OPPROTO op_movl_eflags_T0(void)
935
{
936
    CC_SRC = T0;
937
    DF = (T0 & DIRECTION_FLAG) ? -1 : 1;
938
}
939

  
940
void OPPROTO op_movb_eflags_T0(void)
941
{
942
    int cc_o;
943
    cc_o = cc_table[CC_OP].compute_o();
944
    CC_SRC = T0 | (cc_o << 11);
945
}
946

  
947
void OPPROTO op_movl_T0_eflags(void)
948
{
949
    cc_table[CC_OP].compute_eflags();
950
}
951

  
952
void OPPROTO op_cld(void)
953
{
954
    DF = 1;
955
}
956

  
957
void OPPROTO op_std(void)
958
{
959
    DF = -1;
960
}
961

  
962 506
/* jumps */
963 507

  
964 508
/* indirect jump */
......
972 516
    PC = PARAM1;
973 517
}
974 518

  
975
void OPPROTO op_jne_b(void)
976
{
977
    if ((uint8_t)CC_DST != 0)
978
        PC += PARAM1;
979
    else
980
        PC += PARAM2;
981
    FORCE_RET();
982
}
983

  
984
void OPPROTO op_jne_w(void)
985
{
986
    if ((uint16_t)CC_DST != 0)
987
        PC += PARAM1;
988
    else
989
        PC += PARAM2;
990
    FORCE_RET();
991
}
992

  
993
void OPPROTO op_jne_l(void)
994
{
995
    if (CC_DST != 0)
996
        PC += PARAM1;
997
    else
998
        PC += PARAM2;
999
    FORCE_RET(); /* generate a return so that gcc does not generate an
1000
                    early function return */
1001
}
1002

  
1003 519
/* string ops */
1004 520

  
1005 521
#define ldul ldl
1006 522

  
1007
#define SUFFIX b
1008 523
#define SHIFT 0
1009
#include "opstring_template.h"
1010
#undef SUFFIX
524
#include "ops_template.h"
1011 525
#undef SHIFT
1012 526

  
1013
#define SUFFIX w
1014 527
#define SHIFT 1
1015
#include "opstring_template.h"
1016
#undef SUFFIX
528
#include "ops_template.h"
1017 529
#undef SHIFT
1018 530

  
1019
#define SUFFIX l
1020 531
#define SHIFT 2
1021
#include "opstring_template.h"
1022
#undef SUFFIX
532
#include "ops_template.h"
1023 533
#undef SHIFT
1024 534

  
1025 535
/* sign extend */
......
1095 605
{
1096 606
    ESP += PARAM1;
1097 607
}
608

  
609
/* flags handling */
610

  
611
/* slow jumps cases (compute x86 flags) */
612
void OPPROTO op_jo_cc(void)
613
{
614
    int eflags;
615
    eflags = cc_table[CC_OP].compute_all();
616
    if (eflags & CC_O)
617
        PC += PARAM1;
618
    else
619
        PC += PARAM2;
620
}
621

  
622
void OPPROTO op_jb_cc(void)
623
{
624
    if (cc_table[CC_OP].compute_c())
625
        PC += PARAM1;
626
    else
627
        PC += PARAM2;
628
}
629

  
630
void OPPROTO op_jz_cc(void)
631
{
632
    int eflags;
633
    eflags = cc_table[CC_OP].compute_all();
634
    if (eflags & CC_Z)
635
        PC += PARAM1;
636
    else
637
        PC += PARAM2;
638
}
639

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff