Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-core/src/r4300/x86/assemble.h
2 views
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* Mupen64plus - assemble.h *
3
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4
* Copyright (C) 2002 Hacktarux *
5
* *
6
* This program is free software; you can redistribute it and/or modify *
7
* it under the terms of the GNU General Public License as published by *
8
* the Free Software Foundation; either version 2 of the License, or *
9
* (at your option) any later version. *
10
* *
11
* This program is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU General Public License for more details. *
15
* *
16
* You should have received a copy of the GNU General Public License *
17
* along with this program; if not, write to the *
18
* Free Software Foundation, Inc., *
19
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22
#ifndef ASSEMBLE_H
23
#define ASSEMBLE_H
24
25
#include "r4300/recomph.h"
26
#include "api/callbacks.h"
27
#include "osal/preproc.h"
28
29
#include <stdlib.h>
30
31
extern long long int reg[32];
32
33
#define EAX 0
34
#define ECX 1
35
#define EDX 2
36
#define EBX 3
37
#define ESP 4
38
#define EBP 5
39
#define ESI 6
40
#define EDI 7
41
42
#define AX 0
43
#define CX 1
44
#define DX 2
45
#define BX 3
46
#define SP 4
47
#define BP 5
48
#define SI 6
49
#define DI 7
50
51
#define AL 0
52
#define CL 1
53
#define DL 2
54
#define BL 3
55
#define AH 4
56
#define CH 5
57
#define DH 6
58
#define BH 7
59
60
extern int branch_taken;
61
62
void jump_start_rel8(void);
63
void jump_end_rel8(void);
64
void jump_start_rel32(void);
65
void jump_end_rel32(void);
66
void add_jump(unsigned int pc_addr, unsigned int mi_addr);
67
68
static osal_inline void put8(unsigned char octet)
69
{
70
(*inst_pointer)[code_length] = octet;
71
code_length++;
72
if (code_length == max_code_length)
73
{
74
*inst_pointer = (unsigned char *) realloc_exec(*inst_pointer, max_code_length, max_code_length+8192);
75
max_code_length += 8192;
76
}
77
}
78
79
static osal_inline void put32(unsigned int dword)
80
{
81
if ((code_length+4) >= max_code_length)
82
{
83
*inst_pointer = (unsigned char *) realloc_exec(*inst_pointer, max_code_length, max_code_length+8192);
84
max_code_length += 8192;
85
}
86
*((unsigned int *)(&(*inst_pointer)[code_length])) = dword;
87
code_length+=4;
88
}
89
90
static osal_inline void mov_eax_memoffs32(unsigned int *memoffs32)
91
{
92
put8(0xA1);
93
put32((unsigned int)(memoffs32));
94
}
95
96
static osal_inline void mov_memoffs32_eax(unsigned int *memoffs32)
97
{
98
put8(0xA3);
99
put32((unsigned int)(memoffs32));
100
}
101
102
static osal_inline void mov_m8_reg8(unsigned char *m8, int reg8)
103
{
104
put8(0x88);
105
put8((reg8 << 3) | 5);
106
put32((unsigned int)(m8));
107
}
108
109
static osal_inline void mov_reg16_m16(int reg16, unsigned short *m16)
110
{
111
put8(0x66);
112
put8(0x8B);
113
put8((reg16 << 3) | 5);
114
put32((unsigned int)(m16));
115
}
116
117
static osal_inline void mov_m16_reg16(unsigned short *m16, int reg16)
118
{
119
put8(0x66);
120
put8(0x89);
121
put8((reg16 << 3) | 5);
122
put32((unsigned int)(m16));
123
}
124
125
static osal_inline void cmp_reg32_m32(int reg32, unsigned int *m32)
126
{
127
put8(0x3B);
128
put8((reg32 << 3) | 5);
129
put32((unsigned int)(m32));
130
}
131
132
static osal_inline void cmp_reg32_reg32(int reg1, int reg2)
133
{
134
put8(0x39);
135
put8((reg2 << 3) | reg1 | 0xC0);
136
}
137
138
static osal_inline void cmp_reg32_imm8(int reg32, unsigned char imm8)
139
{
140
put8(0x83);
141
put8(0xF8 + reg32);
142
put8(imm8);
143
}
144
145
static osal_inline void cmp_preg32pimm32_imm8(int reg32, unsigned int imm32, unsigned char imm8)
146
{
147
put8(0x80);
148
put8(0xB8 + reg32);
149
put32(imm32);
150
put8(imm8);
151
}
152
153
static osal_inline void cmp_reg32_imm32(int reg32, unsigned int imm32)
154
{
155
put8(0x81);
156
put8(0xF8 + reg32);
157
put32(imm32);
158
}
159
160
static osal_inline void test_reg32_imm32(int reg32, unsigned int imm32)
161
{
162
put8(0xF7);
163
put8(0xC0 + reg32);
164
put32(imm32);
165
}
166
167
static osal_inline void test_m32_imm32(unsigned int *m32, unsigned int imm32)
168
{
169
put8(0xF7);
170
put8(0x05);
171
put32((unsigned int)m32);
172
put32(imm32);
173
}
174
175
static osal_inline void add_m32_reg32(unsigned int *m32, int reg32)
176
{
177
put8(0x01);
178
put8((reg32 << 3) | 5);
179
put32((unsigned int)(m32));
180
}
181
182
static osal_inline void sub_reg32_m32(int reg32, unsigned int *m32)
183
{
184
put8(0x2B);
185
put8((reg32 << 3) | 5);
186
put32((unsigned int)(m32));
187
}
188
189
static osal_inline void sub_reg32_reg32(int reg1, int reg2)
190
{
191
put8(0x29);
192
put8((reg2 << 3) | reg1 | 0xC0);
193
}
194
195
static osal_inline void sbb_reg32_reg32(int reg1, int reg2)
196
{
197
put8(0x19);
198
put8((reg2 << 3) | reg1 | 0xC0);
199
}
200
201
static osal_inline void sub_reg32_imm32(int reg32, unsigned int imm32)
202
{
203
put8(0x81);
204
put8(0xE8 + reg32);
205
put32(imm32);
206
}
207
208
static osal_inline void sub_eax_imm32(unsigned int imm32)
209
{
210
put8(0x2D);
211
put32(imm32);
212
}
213
214
static osal_inline void jne_rj(unsigned char saut)
215
{
216
put8(0x75);
217
put8(saut);
218
}
219
220
static osal_inline void je_rj(unsigned char saut)
221
{
222
put8(0x74);
223
put8(saut);
224
}
225
226
static osal_inline void jb_rj(unsigned char saut)
227
{
228
put8(0x72);
229
put8(saut);
230
}
231
232
static osal_inline void jbe_rj(unsigned char saut)
233
{
234
put8(0x76);
235
put8(saut);
236
}
237
238
static osal_inline void ja_rj(unsigned char saut)
239
{
240
put8(0x77);
241
put8(saut);
242
}
243
244
static osal_inline void jae_rj(unsigned char saut)
245
{
246
put8(0x73);
247
put8(saut);
248
}
249
250
static osal_inline void jle_rj(unsigned char saut)
251
{
252
put8(0x7E);
253
put8(saut);
254
}
255
256
static osal_inline void jge_rj(unsigned char saut)
257
{
258
put8(0x7D);
259
put8(saut);
260
}
261
262
static osal_inline void jg_rj(unsigned char saut)
263
{
264
put8(0x7F);
265
put8(saut);
266
}
267
268
static osal_inline void jl_rj(unsigned char saut)
269
{
270
put8(0x7C);
271
put8(saut);
272
}
273
274
static osal_inline void jp_rj(unsigned char saut)
275
{
276
put8(0x7A);
277
put8(saut);
278
}
279
280
static osal_inline void je_near_rj(unsigned int saut)
281
{
282
put8(0x0F);
283
put8(0x84);
284
put32(saut);
285
}
286
287
static osal_inline void mov_reg32_imm32(int reg32, unsigned int imm32)
288
{
289
put8(0xB8+reg32);
290
put32(imm32);
291
}
292
293
static osal_inline void jmp_imm_short(char saut)
294
{
295
put8(0xEB);
296
put8(saut);
297
}
298
299
static osal_inline void or_m32_imm32(unsigned int *m32, unsigned int imm32)
300
{
301
put8(0x81);
302
put8(0x0D);
303
put32((unsigned int)(m32));
304
put32(imm32);
305
}
306
307
static osal_inline void or_reg32_reg32(unsigned int reg1, unsigned int reg2)
308
{
309
put8(0x09);
310
put8(0xC0 | (reg2 << 3) | reg1);
311
}
312
313
static osal_inline void and_reg32_reg32(unsigned int reg1, unsigned int reg2)
314
{
315
put8(0x21);
316
put8(0xC0 | (reg2 << 3) | reg1);
317
}
318
319
static osal_inline void and_m32_imm32(unsigned int *m32, unsigned int imm32)
320
{
321
put8(0x81);
322
put8(0x25);
323
put32((unsigned int)(m32));
324
put32(imm32);
325
}
326
327
static osal_inline void xor_reg32_reg32(unsigned int reg1, unsigned int reg2)
328
{
329
put8(0x31);
330
put8(0xC0 | (reg2 << 3) | reg1);
331
}
332
333
static osal_inline void sub_m32_imm32(unsigned int *m32, unsigned int imm32)
334
{
335
put8(0x81);
336
put8(0x2D);
337
put32((unsigned int)(m32));
338
put32(imm32);
339
}
340
341
static osal_inline void add_reg32_imm32(unsigned int reg32, unsigned int imm32)
342
{
343
put8(0x81);
344
put8(0xC0+reg32);
345
put32(imm32);
346
}
347
348
static osal_inline void inc_m32(unsigned int *m32)
349
{
350
put8(0xFF);
351
put8(0x05);
352
put32((unsigned int)(m32));
353
}
354
355
static osal_inline void cmp_m32_imm32(unsigned int *m32, unsigned int imm32)
356
{
357
put8(0x81);
358
put8(0x3D);
359
put32((unsigned int)(m32));
360
put32(imm32);
361
}
362
363
static osal_inline void cmp_eax_imm32(unsigned int imm32)
364
{
365
put8(0x3D);
366
put32(imm32);
367
}
368
369
static osal_inline void mov_m32_imm32(unsigned int *m32, unsigned int imm32)
370
{
371
put8(0xC7);
372
put8(0x05);
373
put32((unsigned int)(m32));
374
put32(imm32);
375
}
376
377
static osal_inline void jmp(unsigned int mi_addr)
378
{
379
put8(0xE9);
380
put32(0);
381
add_jump(code_length-4, mi_addr);
382
}
383
384
static osal_inline void cdq(void)
385
{
386
put8(0x99);
387
}
388
389
static osal_inline void mov_m32_reg32(unsigned int *m32, unsigned int reg32)
390
{
391
put8(0x89);
392
put8((reg32 << 3) | 5);
393
put32((unsigned int)(m32));
394
}
395
396
static osal_inline void call_reg32(unsigned int reg32)
397
{
398
put8(0xFF);
399
put8(0xD0+reg32);
400
}
401
402
static osal_inline void shr_reg32_imm8(unsigned int reg32, unsigned char imm8)
403
{
404
put8(0xC1);
405
put8(0xE8+reg32);
406
put8(imm8);
407
}
408
409
static osal_inline void shr_reg32_cl(unsigned int reg32)
410
{
411
put8(0xD3);
412
put8(0xE8+reg32);
413
}
414
415
static osal_inline void sar_reg32_cl(unsigned int reg32)
416
{
417
put8(0xD3);
418
put8(0xF8+reg32);
419
}
420
421
static osal_inline void shl_reg32_cl(unsigned int reg32)
422
{
423
put8(0xD3);
424
put8(0xE0+reg32);
425
}
426
427
static osal_inline void shld_reg32_reg32_cl(unsigned int reg1, unsigned int reg2)
428
{
429
put8(0x0F);
430
put8(0xA5);
431
put8(0xC0 | (reg2 << 3) | reg1);
432
}
433
434
static osal_inline void shld_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8)
435
{
436
put8(0x0F);
437
put8(0xA4);
438
put8(0xC0 | (reg2 << 3) | reg1);
439
put8(imm8);
440
}
441
442
static osal_inline void shrd_reg32_reg32_cl(unsigned int reg1, unsigned int reg2)
443
{
444
put8(0x0F);
445
put8(0xAD);
446
put8(0xC0 | (reg2 << 3) | reg1);
447
}
448
449
static osal_inline void sar_reg32_imm8(unsigned int reg32, unsigned char imm8)
450
{
451
put8(0xC1);
452
put8(0xF8+reg32);
453
put8(imm8);
454
}
455
456
static osal_inline void shrd_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8)
457
{
458
put8(0x0F);
459
put8(0xAC);
460
put8(0xC0 | (reg2 << 3) | reg1);
461
put8(imm8);
462
}
463
464
static osal_inline void mul_m32(unsigned int *m32)
465
{
466
put8(0xF7);
467
put8(0x25);
468
put32((unsigned int)(m32));
469
}
470
471
static osal_inline void imul_reg32(unsigned int reg32)
472
{
473
put8(0xF7);
474
put8(0xE8+reg32);
475
}
476
477
static osal_inline void mul_reg32(unsigned int reg32)
478
{
479
put8(0xF7);
480
put8(0xE0+reg32);
481
}
482
483
static osal_inline void idiv_reg32(unsigned int reg32)
484
{
485
put8(0xF7);
486
put8(0xF8+reg32);
487
}
488
489
static osal_inline void div_reg32(unsigned int reg32)
490
{
491
put8(0xF7);
492
put8(0xF0+reg32);
493
}
494
495
static osal_inline void add_reg32_reg32(unsigned int reg1, unsigned int reg2)
496
{
497
put8(0x01);
498
put8(0xC0 | (reg2 << 3) | reg1);
499
}
500
501
static osal_inline void adc_reg32_reg32(unsigned int reg1, unsigned int reg2)
502
{
503
put8(0x11);
504
put8(0xC0 | (reg2 << 3) | reg1);
505
}
506
507
static osal_inline void add_reg32_m32(unsigned int reg32, unsigned int *m32)
508
{
509
put8(0x03);
510
put8((reg32 << 3) | 5);
511
put32((unsigned int)(m32));
512
}
513
514
static osal_inline void adc_reg32_imm32(unsigned int reg32, unsigned int imm32)
515
{
516
put8(0x81);
517
put8(0xD0 + reg32);
518
put32(imm32);
519
}
520
521
static osal_inline void jmp_reg32(unsigned int reg32)
522
{
523
put8(0xFF);
524
put8(0xE0 + reg32);
525
}
526
527
static osal_inline void mov_reg32_preg32(unsigned int reg1, unsigned int reg2)
528
{
529
put8(0x8B);
530
put8((reg1 << 3) | reg2);
531
}
532
533
static osal_inline void mov_preg32_reg32(int reg1, int reg2)
534
{
535
put8(0x89);
536
put8((reg2 << 3) | reg1);
537
}
538
539
static osal_inline void mov_reg32_preg32preg32pimm32(int reg1, int reg2, int reg3, unsigned int imm32)
540
{
541
put8(0x8B);
542
put8((reg1 << 3) | 0x84);
543
put8(reg2 | (reg3 << 3));
544
put32(imm32);
545
}
546
547
static osal_inline void mov_reg32_preg32pimm32(int reg1, int reg2, unsigned int imm32)
548
{
549
put8(0x8B);
550
put8(0x80 | (reg1 << 3) | reg2);
551
put32(imm32);
552
}
553
554
static osal_inline void mov_reg32_preg32x4pimm32(int reg1, int reg2, unsigned int imm32)
555
{
556
put8(0x8B);
557
put8((reg1 << 3) | 4);
558
put8(0x80 | (reg2 << 3) | 5);
559
put32(imm32);
560
}
561
562
static osal_inline void mov_preg32pimm32_reg8(int reg32, unsigned int imm32, int reg8)
563
{
564
put8(0x88);
565
put8(0x80 | reg32 | (reg8 << 3));
566
put32(imm32);
567
}
568
569
static osal_inline void mov_preg32pimm32_imm8(int reg32, unsigned int imm32, unsigned char imm8)
570
{
571
put8(0xC6);
572
put8(0x80 + reg32);
573
put32(imm32);
574
put8(imm8);
575
}
576
577
static osal_inline void mov_preg32pimm32_reg16(int reg32, unsigned int imm32, int reg16)
578
{
579
put8(0x66);
580
put8(0x89);
581
put8(0x80 | reg32 | (reg16 << 3));
582
put32(imm32);
583
}
584
585
static osal_inline void mov_preg32pimm32_reg32(int reg1, unsigned int imm32, int reg2)
586
{
587
put8(0x89);
588
put8(0x80 | reg1 | (reg2 << 3));
589
put32(imm32);
590
}
591
592
static osal_inline void add_eax_imm32(unsigned int imm32)
593
{
594
put8(0x05);
595
put32(imm32);
596
}
597
598
static osal_inline void shl_reg32_imm8(unsigned int reg32, unsigned char imm8)
599
{
600
put8(0xC1);
601
put8(0xE0 + reg32);
602
put8(imm8);
603
}
604
605
static osal_inline void mov_reg32_m32(unsigned int reg32, unsigned int* m32)
606
{
607
put8(0x8B);
608
put8((reg32 << 3) | 5);
609
put32((unsigned int)(m32));
610
}
611
612
static osal_inline void mov_reg8_m8(int reg8, unsigned char *m8)
613
{
614
put8(0x8A);
615
put8((reg8 << 3) | 5);
616
put32((unsigned int)(m8));
617
}
618
619
static osal_inline void and_eax_imm32(unsigned int imm32)
620
{
621
put8(0x25);
622
put32(imm32);
623
}
624
625
static osal_inline void and_reg32_imm32(int reg32, unsigned int imm32)
626
{
627
put8(0x81);
628
put8(0xE0 + reg32);
629
put32(imm32);
630
}
631
632
static osal_inline void or_reg32_imm32(int reg32, unsigned int imm32)
633
{
634
put8(0x81);
635
put8(0xC8 + reg32);
636
put32(imm32);
637
}
638
639
static osal_inline void xor_reg32_imm32(int reg32, unsigned int imm32)
640
{
641
put8(0x81);
642
put8(0xF0 + reg32);
643
put32(imm32);
644
}
645
646
static osal_inline void xor_reg8_imm8(int reg8, unsigned char imm8)
647
{
648
put8(0x80);
649
put8(0xF0 + reg8);
650
put8(imm8);
651
}
652
653
static osal_inline void mov_reg32_reg32(unsigned int reg1, unsigned int reg2)
654
{
655
if (reg1 == reg2) return;
656
put8(0x89);
657
put8(0xC0 | (reg2 << 3) | reg1);
658
}
659
660
static osal_inline void not_reg32(unsigned int reg32)
661
{
662
put8(0xF7);
663
put8(0xD0 + reg32);
664
}
665
666
static osal_inline void movsx_reg32_m8(int reg32, unsigned char *m8)
667
{
668
put8(0x0F);
669
put8(0xBE);
670
put8((reg32 << 3) | 5);
671
put32((unsigned int)(m8));
672
}
673
674
static osal_inline void movsx_reg32_8preg32pimm32(int reg1, int reg2, unsigned int imm32)
675
{
676
put8(0x0F);
677
put8(0xBE);
678
put8((reg1 << 3) | reg2 | 0x80);
679
put32(imm32);
680
}
681
682
static osal_inline void movsx_reg32_16preg32pimm32(int reg1, int reg2, unsigned int imm32)
683
{
684
put8(0x0F);
685
put8(0xBF);
686
put8((reg1 << 3) | reg2 | 0x80);
687
put32(imm32);
688
}
689
690
static osal_inline void movsx_reg32_m16(int reg32, unsigned short *m16)
691
{
692
put8(0x0F);
693
put8(0xBF);
694
put8((reg32 << 3) | 5);
695
put32((unsigned int)(m16));
696
}
697
698
static osal_inline void fldcw_m16(unsigned short *m16)
699
{
700
put8(0xD9);
701
put8(0x2D);
702
put32((unsigned int)(m16));
703
}
704
705
static osal_inline void fld_preg32_dword(int reg32)
706
{
707
put8(0xD9);
708
put8(reg32);
709
}
710
711
static osal_inline void fdiv_preg32_dword(int reg32)
712
{
713
put8(0xD8);
714
put8(0x30 + reg32);
715
}
716
717
static osal_inline void fstp_preg32_dword(int reg32)
718
{
719
put8(0xD9);
720
put8(0x18 + reg32);
721
}
722
723
static osal_inline void fchs(void)
724
{
725
put8(0xD9);
726
put8(0xE0);
727
}
728
729
static osal_inline void fstp_preg32_qword(int reg32)
730
{
731
put8(0xDD);
732
put8(0x18 + reg32);
733
}
734
735
static osal_inline void fadd_preg32_dword(int reg32)
736
{
737
put8(0xD8);
738
put8(reg32);
739
}
740
741
static osal_inline void fsub_preg32_dword(int reg32)
742
{
743
put8(0xD8);
744
put8(0x20 + reg32);
745
}
746
747
static osal_inline void fmul_preg32_dword(int reg32)
748
{
749
put8(0xD8);
750
put8(0x08 + reg32);
751
}
752
753
static osal_inline void fistp_preg32_dword(int reg32)
754
{
755
put8(0xDB);
756
put8(0x18 + reg32);
757
}
758
759
static osal_inline void fistp_preg32_qword(int reg32)
760
{
761
put8(0xDF);
762
put8(0x38 + reg32);
763
}
764
765
static osal_inline void fld_preg32_qword(int reg32)
766
{
767
put8(0xDD);
768
put8(reg32);
769
}
770
771
static osal_inline void fild_preg32_qword(int reg32)
772
{
773
put8(0xDF);
774
put8(0x28+reg32);
775
}
776
777
static osal_inline void fild_preg32_dword(int reg32)
778
{
779
put8(0xDB);
780
put8(reg32);
781
}
782
783
static osal_inline void fadd_preg32_qword(int reg32)
784
{
785
put8(0xDC);
786
put8(reg32);
787
}
788
789
static osal_inline void fdiv_preg32_qword(int reg32)
790
{
791
put8(0xDC);
792
put8(0x30 + reg32);
793
}
794
795
static osal_inline void fsub_preg32_qword(int reg32)
796
{
797
put8(0xDC);
798
put8(0x20 + reg32);
799
}
800
801
static osal_inline void fmul_preg32_qword(int reg32)
802
{
803
put8(0xDC);
804
put8(0x08 + reg32);
805
}
806
807
static osal_inline void fsqrt(void)
808
{
809
put8(0xD9);
810
put8(0xFA);
811
}
812
813
static osal_inline void fabs_(void)
814
{
815
put8(0xD9);
816
put8(0xE1);
817
}
818
819
static osal_inline void fcomip_fpreg(int fpreg)
820
{
821
put8(0xDF);
822
put8(0xF0 + fpreg);
823
}
824
825
static osal_inline void fucomip_fpreg(int fpreg)
826
{
827
put8(0xDF);
828
put8(0xE8 + fpreg);
829
}
830
831
static osal_inline void ffree_fpreg(int fpreg)
832
{
833
put8(0xDD);
834
put8(0xC0 + fpreg);
835
}
836
837
#endif // ASSEMBLE_H
838
839
840