annotate arm/gen.c @ 546:3f683703c8db

Rename ggoto() to gen_goto().
author Rob Landley <rob@landley.net>
date Fri, 28 Dec 2007 17:33:06 -0600
parents 95fd7f30f7e3
children d1fe34c5b92e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1 /*
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
2 * ARMv4 code generator for TCC
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
3 *
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
4 * Copyright (c) 2003 Daniel Glöckner
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
5 *
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
6 * Based on i386-gen.c by Fabrice Bellard
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
7 *
499
2b451d2e68ea Exercise LGPL clause 3 and convert more notices from LGPL to GPLv2. (If you
Rob Landley <rob@landley.net>
parents: 410
diff changeset
8 * Licensed under GPLv2, see file LICENSE in this tarball.
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
9 */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
10
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
11 #ifdef TCC_ARM_EABI
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
12 #define TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
13 #endif
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
14
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
15
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
16 /* number of available registers */
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
17 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
18 #define NB_REGS 13
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
19 #else
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
20 #define NB_REGS 9
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
21 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
22
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
23 /* a register can belong to several classes. The classes must be
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
24 sorted from more general to more precise (see gv2() code which does
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
25 assumptions on it). */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
26 #define RC_INT 0x0001 /* generic integer register */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
27 #define RC_FLOAT 0x0002 /* generic float register */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
28 #define RC_R0 0x0004
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
29 #define RC_R1 0x0008
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
30 #define RC_R2 0x0010
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
31 #define RC_R3 0x0020
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
32 #define RC_R12 0x0040
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
33 #define RC_F0 0x0080
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
34 #define RC_F1 0x0100
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
35 #define RC_F2 0x0200
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
36 #define RC_F3 0x0400
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
37 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
38 #define RC_F4 0x0800
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
39 #define RC_F5 0x1000
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
40 #define RC_F6 0x2000
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
41 #define RC_F7 0x4000
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
42 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
43 #define RC_IRET RC_R0 /* function return: integer register */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
44 #define RC_LRET RC_R1 /* function return: second integer register */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
45 #define RC_FRET RC_F0 /* function return: float register */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
46
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
47 /* pretty names for the registers */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
48 enum {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
49 TREG_R0 = 0,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
50 TREG_R1,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
51 TREG_R2,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
52 TREG_R3,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
53 TREG_R12,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
54 TREG_F0,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
55 TREG_F1,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
56 TREG_F2,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
57 TREG_F3,
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
58 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
59 TREG_F4,
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
60 TREG_F5,
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
61 TREG_F6,
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
62 TREG_F7,
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
63 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
64 };
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
65
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
66 int reg_classes[NB_REGS] = {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
67 /* r0 */ RC_INT | RC_R0,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
68 /* r1 */ RC_INT | RC_R1,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
69 /* r2 */ RC_INT | RC_R2,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
70 /* r3 */ RC_INT | RC_R3,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
71 /* r12 */ RC_INT | RC_R12,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
72 /* f0 */ RC_FLOAT | RC_F0,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
73 /* f1 */ RC_FLOAT | RC_F1,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
74 /* f2 */ RC_FLOAT | RC_F2,
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
75 /* f3 */ RC_FLOAT | RC_F3,
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
76 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
77 /* d4/s8 */ RC_FLOAT | RC_F4,
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
78 /* d5/s10 */ RC_FLOAT | RC_F5,
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
79 /* d6/s12 */ RC_FLOAT | RC_F6,
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
80 /* d7/s14 */ RC_FLOAT | RC_F7,
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
81 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
82 };
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
83
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
84 static int two2mask(int a,int b) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
85 return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
86 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
87
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
88 static int regmask(int r) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
89 return reg_classes[r]&~(RC_INT|RC_FLOAT);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
90 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
91
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
92 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
93 #define T2CPR(t) (((t) & VT_BTYPE) != VT_FLOAT ? 0x100 : 0)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
94 #endif
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
95
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
96 /* return registers for function */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
97 #define REG_IRET TREG_R0 /* single word int return register */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
98 #define REG_LRET TREG_R1 /* second word return register (for long long) */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
99 #define REG_FRET TREG_F0 /* float return register */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
100
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
101 /* defined if function parameters must be evaluated in reverse order */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
102 #define INVERT_FUNC_PARAMS
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
103
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
104 /* defined if structures are passed as pointers. Otherwise structures
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
105 are directly pushed on stack. */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
106 //#define FUNC_STRUCT_PARAM_AS_PTR
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
107
410
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
108 #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
109 static CType float_type, double_type, func_float_type, func_double_type;
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
110 #endif
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
111
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
112 /* pointer size, in bytes */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
113 #define PTR_SIZE 4
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
114
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
115 /* long double size and alignment, in bytes */
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
116 #ifdef TCC_ARM_VFP
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
117 #define LDOUBLE_SIZE 8
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
118 #endif
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
119
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
120 #ifndef LDOUBLE_SIZE
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
121 #define LDOUBLE_SIZE 8
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
122 #endif
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
123
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
124 #ifdef TCC_ARM_EABI
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
125 #define LDOUBLE_ALIGN 8
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
126 #else
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
127 #define LDOUBLE_ALIGN 4
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
128 #endif
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
129
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
130 /* maximum alignment (for aligned attribute support) */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
131 #define MAX_ALIGN 8
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
132
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
133 #define CHAR_IS_UNSIGNED
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
134
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
135 /******************************************************/
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
136 /* ELF defines */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
137
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
138 #define EM_TCC_TARGET EM_ARM
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
139
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
140 /* relocation type for 32 bit data relocation */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
141 #define R_DATA_32 R_ARM_ABS32
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
142 #define R_JMP_SLOT R_ARM_JUMP_SLOT
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
143 #define R_COPY R_ARM_COPY
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
144
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
145 #define ELF_START_ADDR 0x00008000
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
146 #define ELF_PAGE_SIZE 0x1000
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
147
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
148 /******************************************************/
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
149 static unsigned long func_sub_sp_offset,last_itod_magic;
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
150 static int leaffunc;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
151
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
152 void o(unsigned long i)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
153 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
154 /* this is a good place to start adding big-endian support*/
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
155 int ind1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
156
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
157 ind1 = ind + 4;
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
158 if (!cur_text_section)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
159 error("compiler error! This happens f.ex. if the compiler\n"
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
160 "can't evaluate constant expressions outside of a function.");
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
161 if (ind1 > cur_text_section->data_allocated)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
162 section_realloc(cur_text_section, ind1);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
163 cur_text_section->data[ind++] = i&255;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
164 i>>=8;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
165 cur_text_section->data[ind++] = i&255;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
166 i>>=8;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
167 cur_text_section->data[ind++] = i&255;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
168 i>>=8;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
169 cur_text_section->data[ind++] = i;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
170 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
171
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
172 static unsigned long stuff_const(unsigned long op,unsigned long c)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
173 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
174 int try_neg=0;
337
ab2fa6ee2e59 [project @ 2004-11-07 15:43:15 by bellard]
bellard
parents: 307
diff changeset
175 unsigned long nc = 0,negop = 0;
ab2fa6ee2e59 [project @ 2004-11-07 15:43:15 by bellard]
bellard
parents: 307
diff changeset
176
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
177 switch(op&0x1F00000)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
178 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
179 case 0x800000: //add
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
180 case 0x400000: //sub
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
181 try_neg=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
182 negop=op^0xC00000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
183 nc=-c;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
184 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
185 case 0x1A00000: //mov
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
186 case 0x1E00000: //mvn
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
187 try_neg=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
188 negop=op^0x400000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
189 nc=~c;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
190 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
191 case 0x200000: //xor
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
192 if(c==~0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
193 return (op&0xF010F000)|((op>>16)&0xF)|0x1E00000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
194 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
195 case 0x0: //and
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
196 if(c==~0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
197 return (op&0xF010F000)|((op>>16)&0xF)|0x1A00000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
198 case 0x1C00000: //bic
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
199 try_neg=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
200 negop=op^0x1C00000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
201 nc=~c;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
202 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
203 case 0x1800000: //orr
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
204 if(c==~0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
205 return (op&0xFFF0FFFF)|0x1E00000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
206 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
207 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
208 do {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
209 unsigned long m;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
210 int i;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
211 if(c<256) /* catch undefined <<32 */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
212 return op|c;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
213 for(i=2;i<32;i+=2) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
214 m=(0xff>>i)|(0xff<<(32-i));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
215 if(!(c&~m))
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
216 return op|(i<<7)|(c<<i)|(c>>(32-i));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
217 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
218 op=negop;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
219 c=nc;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
220 } while(try_neg--);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
221 return 0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
222 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
223
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
224
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
225 //only add,sub
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
226 void stuff_const_harder(unsigned long op,unsigned long v) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
227 unsigned long x;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
228 x=stuff_const(op,v);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
229 if(x)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
230 o(x);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
231 else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
232 unsigned long a[16],nv,no,o2,n2;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
233 int i,j,k;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
234 a[0]=0xff;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
235 o2=(op&0xfff0ffff)|((op&0xf000)<<4);;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
236 for(i=1;i<16;i++)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
237 a[i]=(a[i-1]>>2)|(a[i-1]<<30);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
238 for(i=0;i<12;i++)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
239 for(j=i+4;i<13+i;i++)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
240 if((v&(a[i]|a[j]))==v) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
241 o(stuff_const(op,v&a[i]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
242 o(stuff_const(o2,v&a[j]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
243 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
244 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
245 no=op^0xC00000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
246 n2=o2^0xC00000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
247 nv=-v;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
248 for(i=0;i<12;i++)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
249 for(j=i+4;i<13+i;i++)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
250 if((nv&(a[i]|a[j]))==nv) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
251 o(stuff_const(no,nv&a[i]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
252 o(stuff_const(n2,nv&a[j]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
253 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
254 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
255 for(i=0;i<8;i++)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
256 for(j=i+4;i<12;i++)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
257 for(k=j+4;k<13+i;i++)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
258 if((v&(a[i]|a[j]|a[k]))==v) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
259 o(stuff_const(op,v&a[i]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
260 o(stuff_const(o2,v&a[j]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
261 o(stuff_const(o2,v&a[k]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
262 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
263 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
264 no=op^0xC00000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
265 nv=-v;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
266 for(i=0;i<8;i++)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
267 for(j=i+4;i<12;i++)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
268 for(k=j+4;k<13+i;i++)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
269 if((nv&(a[i]|a[j]|a[k]))==nv) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
270 o(stuff_const(no,nv&a[i]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
271 o(stuff_const(n2,nv&a[j]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
272 o(stuff_const(n2,nv&a[k]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
273 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
274 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
275 o(stuff_const(op,v&a[0]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
276 o(stuff_const(o2,v&a[4]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
277 o(stuff_const(o2,v&a[8]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
278 o(stuff_const(o2,v&a[12]));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
279 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
280 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
281
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
282 unsigned long encbranch(int pos,int addr,int fail)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
283 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
284 addr-=pos+8;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
285 addr/=4;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
286 if(addr>=0x1000000 || addr<-0x1000000) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
287 if(fail)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
288 error("FIXME: function bigger than 32MB");
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
289 return 0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
290 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
291 return 0x0A000000|(addr&0xffffff);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
292 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
293
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
294 int decbranch(int pos)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
295 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
296 int x;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
297 x=*(int *)(cur_text_section->data + pos);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
298 x&=0x00ffffff;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
299 if(x&0x800000)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
300 x-=0x1000000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
301 return x*4+pos+8;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
302 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
303
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
304 /* output a symbol and patch all calls to it */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
305 void gsym_addr(int t, int a)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
306 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
307 unsigned long *x;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
308 int lt;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
309 while(t) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
310 x=(unsigned long *)(cur_text_section->data + t);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
311 t=decbranch(lt=t);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
312 if(a==lt+4)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
313 *x=0xE1A00000; // nop
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
314 else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
315 *x &= 0xff000000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
316 *x |= encbranch(lt,a,1);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
317 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
318 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
319 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
320
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
321 void gsym(int t)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
322 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
323 gsym_addr(t, ind);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
324 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
325
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
326 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
327 static unsigned long vfpr(int r)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
328 {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
329 if(r<TREG_F0 || r>TREG_F7)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
330 error("compiler error! register %i is no vfp register",r);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
331 return r-5;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
332 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
333 #else
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
334 static unsigned long fpr(int r)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
335 {
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
336 if(r<TREG_F0 || r>TREG_F3)
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
337 error("compiler error! register %i is no fpa register",r);
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
338 return r-5;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
339 }
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
340 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
341
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
342 static unsigned long intr(int r)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
343 {
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
344 if(r==4)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
345 return 12;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
346 if((r<0 || r>4) && r!=14)
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
347 error("compiler error! register %i is no int register",r);
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
348 return r;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
349 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
350
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
351 static void calcaddr(unsigned long *base,int *off,int *sgn,int maxoff,unsigned shift)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
352 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
353 if(*off>maxoff || *off&((1<<shift)-1)) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
354 unsigned long x,y;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
355 x=0xE280E000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
356 if(*sgn)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
357 x=0xE240E000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
358 x|=(*base)<<16;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
359 *base=14; // lr
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
360 y=stuff_const(x,*off&~maxoff);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
361 if(y) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
362 o(y);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
363 *off&=maxoff;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
364 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
365 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
366 y=stuff_const(x,(*off+maxoff)&~maxoff);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
367 if(y) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
368 o(y);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
369 *sgn=!*sgn;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
370 *off=((*off+maxoff)&~maxoff)-*off;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
371 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
372 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
373 stuff_const_harder(x,*off&~maxoff);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
374 *off&=maxoff;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
375 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
376 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
377
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
378 static unsigned long mapcc(int cc)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
379 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
380 switch(cc)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
381 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
382 case TOK_ULT:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
383 return 0x30000000; /* CC/LO */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
384 case TOK_UGE:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
385 return 0x20000000; /* CS/HS */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
386 case TOK_EQ:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
387 return 0x00000000; /* EQ */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
388 case TOK_NE:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
389 return 0x10000000; /* NE */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
390 case TOK_ULE:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
391 return 0x90000000; /* LS */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
392 case TOK_UGT:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
393 return 0x80000000; /* HI */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
394 case TOK_Nset:
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
395 return 0x40000000; /* MI */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
396 case TOK_Nclear:
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
397 return 0x50000000; /* PL */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
398 case TOK_LT:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
399 return 0xB0000000; /* LT */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
400 case TOK_GE:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
401 return 0xA0000000; /* GE */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
402 case TOK_LE:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
403 return 0xD0000000; /* LE */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
404 case TOK_GT:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
405 return 0xC0000000; /* GT */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
406 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
407 error("unexpected condition code");
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
408 return 0xE0000000; /* AL */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
409 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
410
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
411 static int negcc(int cc)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
412 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
413 switch(cc)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
414 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
415 case TOK_ULT:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
416 return TOK_UGE;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
417 case TOK_UGE:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
418 return TOK_ULT;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
419 case TOK_EQ:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
420 return TOK_NE;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
421 case TOK_NE:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
422 return TOK_EQ;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
423 case TOK_ULE:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
424 return TOK_UGT;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
425 case TOK_UGT:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
426 return TOK_ULE;
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
427 case TOK_Nset:
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
428 return TOK_Nclear;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
429 case TOK_Nclear:
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
430 return TOK_Nset;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
431 case TOK_LT:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
432 return TOK_GE;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
433 case TOK_GE:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
434 return TOK_LT;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
435 case TOK_LE:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
436 return TOK_GT;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
437 case TOK_GT:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
438 return TOK_LE;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
439 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
440 error("unexpected condition code");
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
441 return TOK_NE;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
442 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
443
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
444 /* load 'r' from value 'sv' */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
445 void load(int r, SValue *sv)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
446 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
447 int v, ft, fc, fr, sign;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
448 unsigned long op;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
449 SValue v1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
450
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
451 fr = sv->r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
452 ft = sv->type.t;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
453 fc = sv->c.ul;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
454
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
455 if(fc>=0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
456 sign=0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
457 else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
458 sign=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
459 fc=-fc;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
460 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
461
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
462 v = fr & VT_VALMASK;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
463 if (fr & VT_LVAL) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
464 unsigned long base=0xB; // fp
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
465 if(v == VT_LLOCAL) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
466 v1.type.t = VT_PTR;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
467 v1.r = VT_LOCAL | VT_LVAL;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
468 v1.c.ul = sv->c.ul;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
469 load(base=14 /* lr */, &v1);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
470 fc=sign=0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
471 v=VT_LOCAL;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
472 } else if(v == VT_CONST) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
473 v1.type.t = VT_PTR;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
474 v1.r = fr&~VT_LVAL;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
475 v1.c.ul = sv->c.ul;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
476 v1.sym=sv->sym;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
477 load(base=14, &v1);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
478 fc=sign=0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
479 v=VT_LOCAL;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
480 } else if(v < VT_CONST) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
481 base=intr(v);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
482 fc=sign=0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
483 v=VT_LOCAL;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
484 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
485 if(v == VT_LOCAL) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
486 if(is_float(ft)) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
487 calcaddr(&base,&fc,&sign,1020,2);
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
488 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
489 op=0xED100A00; /* flds */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
490 if(!sign)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
491 op|=0x800000;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
492 if ((ft & VT_BTYPE) != VT_FLOAT)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
493 op|=0x100; /* flds -> fldd */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
494 o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
495 #else
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
496 op=0xED100100;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
497 if(!sign)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
498 op|=0x800000;
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
499 #if LDOUBLE_SIZE == 8
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
500 if ((ft & VT_BTYPE) != VT_FLOAT)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
501 op|=0x8000;
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
502 #else
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
503 if ((ft & VT_BTYPE) == VT_DOUBLE)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
504 op|=0x8000;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
505 else if ((ft & VT_BTYPE) == VT_LDOUBLE)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
506 op|=0x400000;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
507 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
508 o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
509 #endif
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
510 } else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
511 || (ft & VT_BTYPE) == VT_SHORT) {
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
512 calcaddr(&base,&fc,&sign,255,0);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
513 op=0xE1500090;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
514 if ((ft & VT_BTYPE) == VT_SHORT)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
515 op|=0x20;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
516 if ((ft & VT_UNSIGNED) == 0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
517 op|=0x40;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
518 if(!sign)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
519 op|=0x800000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
520 o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
521 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
522 calcaddr(&base,&fc,&sign,4095,0);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
523 op=0xE5100000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
524 if(!sign)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
525 op|=0x800000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
526 if ((ft & VT_BTYPE) == VT_BYTE)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
527 op|=0x400000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
528 o(op|(intr(r)<<12)|fc|(base<<16));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
529 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
530 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
531 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
532 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
533 if (v == VT_CONST) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
534 op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.ul);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
535 if (fr & VT_SYM || !op) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
536 o(0xE59F0000|(intr(r)<<12));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
537 o(0xEA000000);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
538 if(fr & VT_SYM)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
539 greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
540 o(sv->c.ul);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
541 } else
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
542 o(op);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
543 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
544 } else if (v == VT_LOCAL) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
545 op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.ul);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
546 if (fr & VT_SYM || !op) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
547 o(0xE59F0000|(intr(r)<<12));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
548 o(0xEA000000);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
549 if(fr & VT_SYM) // needed ?
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
550 greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
551 o(sv->c.ul);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
552 o(0xE08B0000|(intr(r)<<12)|intr(r));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
553 } else
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
554 o(op);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
555 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
556 } else if(v == VT_CMP) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
557 o(mapcc(sv->c.ul)|0x3A00001|(intr(r)<<12));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
558 o(mapcc(negcc(sv->c.ul))|0x3A00000|(intr(r)<<12));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
559 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
560 } else if (v == VT_JMP || v == VT_JMPI) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
561 int t;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
562 t = v & 1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
563 o(0xE3A00000|(intr(r)<<12)|t);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
564 o(0xEA000000);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
565 gsym(sv->c.ul);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
566 o(0xE3A00000|(intr(r)<<12)|(t^1));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
567 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
568 } else if (v < VT_CONST) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
569 if(is_float(ft))
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
570 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
571 o(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
572 #else
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
573 o(0xEE008180|(fpr(r)<<12)|fpr(v));
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
574 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
575 else
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
576 o(0xE1A00000|(intr(r)<<12)|intr(v));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
577 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
578 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
579 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
580 error("load unimplemented!");
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
581 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
582
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
583 /* store register 'r' in lvalue 'v' */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
584 void store(int r, SValue *sv)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
585 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
586 SValue v1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
587 int v, ft, fc, fr, sign;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
588 unsigned long op;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
589
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
590 fr = sv->r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
591 ft = sv->type.t;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
592 fc = sv->c.ul;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
593
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
594 if(fc>=0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
595 sign=0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
596 else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
597 sign=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
598 fc=-fc;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
599 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
600
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
601 v = fr & VT_VALMASK;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
602 if (fr & VT_LVAL || fr == VT_LOCAL) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
603 unsigned long base=0xb;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
604 if(v < VT_CONST) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
605 base=intr(v);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
606 v=VT_LOCAL;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
607 fc=sign=0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
608 } else if(v == VT_CONST) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
609 v1.type.t = ft;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
610 v1.r = fr&~VT_LVAL;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
611 v1.c.ul = sv->c.ul;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
612 v1.sym=sv->sym;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
613 load(base=14, &v1);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
614 fc=sign=0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
615 v=VT_LOCAL;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
616 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
617 if(v == VT_LOCAL) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
618 if(is_float(ft)) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
619 calcaddr(&base,&fc,&sign,1020,2);
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
620 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
621 op=0xED000A00; /* fsts */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
622 if(!sign)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
623 op|=0x800000;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
624 if ((ft & VT_BTYPE) != VT_FLOAT)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
625 op|=0x100; /* fsts -> fstd */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
626 o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
627 #else
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
628 op=0xED000100;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
629 if(!sign)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
630 op|=0x800000;
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
631 #if LDOUBLE_SIZE == 8
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
632 if ((ft & VT_BTYPE) != VT_FLOAT)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
633 op|=0x8000;
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
634 #else
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
635 if ((ft & VT_BTYPE) == VT_DOUBLE)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
636 op|=0x8000;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
637 if ((ft & VT_BTYPE) == VT_LDOUBLE)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
638 op|=0x400000;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
639 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
640 o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
641 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
642 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
643 } else if((ft & VT_BTYPE) == VT_SHORT) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
644 calcaddr(&base,&fc,&sign,255,0);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
645 op=0xE14000B0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
646 if(!sign)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
647 op|=0x800000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
648 o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
649 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
650 calcaddr(&base,&fc,&sign,4095,0);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
651 op=0xE5000000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
652 if(!sign)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
653 op|=0x800000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
654 if ((ft & VT_BTYPE) == VT_BYTE)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
655 op|=0x400000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
656 o(op|(intr(r)<<12)|fc|(base<<16));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
657 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
658 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
659 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
660 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
661 error("store unimplemented");
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
662 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
663
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
664 static void gadd_sp(int val)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
665 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
666 stuff_const_harder(0xE28DD000,val);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
667 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
668
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
669 /* 'is_jmp' is '1' if it is a jump */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
670 static void gcall_or_jmp(int is_jmp)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
671 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
672 int r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
673 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
674 unsigned long x;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
675 /* constant case */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
676 x=encbranch(ind,ind+vtop->c.ul,0);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
677 if(x) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
678 if (vtop->r & VT_SYM) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
679 /* relocation case */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
680 greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
681 } else
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
682 put_elf_reloc(symtab_section, cur_text_section, ind, R_ARM_PC24, 0);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
683 o(x|(is_jmp?0xE0000000:0xE1000000));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
684 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
685 if(!is_jmp)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
686 o(0xE28FE004); // add lr,pc,#4
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
687 o(0xE51FF004); // ldr pc,[pc,#-4]
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
688 if (vtop->r & VT_SYM)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
689 greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
690 o(vtop->c.ul);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
691 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
692 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
693 /* otherwise, indirect call */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
694 r = gv(RC_INT);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
695 if(!is_jmp)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
696 o(0xE1A0E00F); // mov lr,pc
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
697 o(0xE1A0F000|intr(r)); // mov pc,r
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
698 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
699 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
700
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
701 /* Generate function call. The function address is pushed first, then
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
702 all the parameters in call order. This functions pops all the
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
703 parameters and the function address. */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
704 void gfunc_call(int nb_args)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
705 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
706 int size, align, r, args_size, i;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
707 Sym *func_sym;
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
708 signed char plan[4][2]={{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
709 int todo=0xf, keep, plan2[4]={0,0,0,0};
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
710
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
711 r = vtop->r & VT_VALMASK;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
712 if (r == VT_CMP || (r & ~1) == VT_JMP)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
713 gv(RC_INT);
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
714 #ifdef TCC_ARM_EABI
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
715 if((vtop[-nb_args].type.ref->type.t & VT_BTYPE) == VT_STRUCT
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
716 && type_size(&vtop[-nb_args].type, &align) <= 4) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
717 SValue tmp;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
718 tmp=vtop[-nb_args];
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
719 vtop[-nb_args]=vtop[-nb_args+1];
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
720 vtop[-nb_args+1]=tmp;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
721 --nb_args;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
722 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
723
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
724 vpushi(0);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
725 vtop->type.t = VT_LLONG;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
726 args_size = 0;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
727 for(i = nb_args + 1 ; i-- ;) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
728 size = type_size(&vtop[-i].type, &align);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
729 if(args_size & (align-1)) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
730 vpushi(0);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
731 vtop->type.t = VT_VOID; /* padding */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
732 vrott(i+2);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
733 args_size += 4;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
734 ++nb_args;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
735 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
736 args_size += (size + 3) & -4;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
737 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
738 vtop--;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
739 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
740 args_size = 0;
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
741 for(i = nb_args ; i-- && args_size < 16 ;) {
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
742 switch(vtop[-i].type.t & VT_BTYPE) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
743 case VT_STRUCT:
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
744 case VT_FLOAT:
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
745 case VT_DOUBLE:
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
746 case VT_LDOUBLE:
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
747 size = type_size(&vtop[-i].type, &align);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
748 size = (size + 3) & -4;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
749 args_size += size;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
750 break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
751 default:
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
752 plan[nb_args-1-i][0]=args_size/4;
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
753 args_size += 4;
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
754 if ((vtop[-i].type.t & VT_BTYPE) == VT_LLONG && args_size < 16) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
755 plan[nb_args-1-i][1]=args_size/4;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
756 args_size += 4;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
757 }
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
758 }
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
759 }
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
760 args_size = keep = 0;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
761 for(i = 0;i < nb_args; i++) {
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
762 vnrott(keep+1);
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
763 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
764 size = type_size(&vtop->type, &align);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
765 /* align to stack align size */
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
766 size = (size + 3) & -4;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
767 /* allocate the necessary size on stack */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
768 gadd_sp(-size);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
769 /* generate structure store */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
770 r = get_reg(RC_INT);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
771 o(0xE1A0000D|(intr(r)<<12));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
772 vset(&vtop->type, r | VT_LVAL, 0);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
773 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
774 vstore();
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
775 vtop--;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
776 args_size += size;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
777 } else if (is_float(vtop->type.t)) {
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
778 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
779 r=vfpr(gv(RC_FLOAT))<<12;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
780 size=4;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
781 if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
782 {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
783 size=8;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
784 r|=0x101; /* fstms -> fstmd */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
785 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
786 o(0xED2D0A01+r);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
787 #else
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
788 r=fpr(gv(RC_FLOAT))<<12;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
789 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
790 size = 4;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
791 else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
792 size = 8;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
793 else
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
794 size = LDOUBLE_SIZE;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
795
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
796 if (size == 12)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
797 r|=0x400000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
798 else if(size == 8)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
799 r|=0x8000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
800
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
801 o(0xED2D0100|r|(size>>2));
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
802 #endif
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
803 vtop--;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
804 args_size += size;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
805 } else {
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
806 int s;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
807 /* simple type (currently always same size) */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
808 /* XXX: implicit cast ? */
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
809 size=4;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
810 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
811 lexpand_nr();
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
812 s=RC_INT;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
813 if(nb_args-i<5 && plan[nb_args-i-1][1]!=-1) {
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
814 s=regmask(plan[nb_args-i-1][1]);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
815 todo&=~(1<<plan[nb_args-i-1][1]);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
816 }
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
817 if(s==RC_INT) {
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
818 r = gv(s);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
819 o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
820 vtop--;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
821 } else {
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
822 plan2[keep]=s;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
823 keep++;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
824 vswap();
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
825 }
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
826 size = 8;
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
827 }
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
828 s=RC_INT;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
829 if(nb_args-i<5 && plan[nb_args-i-1][0]!=-1) {
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
830 s=regmask(plan[nb_args-i-1][0]);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
831 todo&=~(1<<plan[nb_args-i-1][0]);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
832 }
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
833 #ifdef TCC_ARM_EABI
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
834 if(vtop->type.t == VT_VOID) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
835 if(s == RC_INT)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
836 o(0xE24DD004); /* sub sp,sp,#4 */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
837 vtop--;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
838 } else
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
839 #endif
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
840 if(s == RC_INT) {
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
841 r = gv(s);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
842 o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
843 vtop--;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
844 } else {
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
845 plan2[keep]=s;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
846 keep++;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
847 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
848 args_size += size;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
849 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
850 }
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
851 for(i=keep;i--;) {
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
852 gv(plan2[i]);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
853 vrott(keep);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
854 }
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
855 save_regs(keep); /* save used temporary registers */
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
856 keep++;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
857 if(args_size) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
858 int n;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
859 n=args_size/4;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
860 if(n>4)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
861 n=4;
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
862 todo&=((1<<n)-1);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
863 if(todo) {
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
864 int i;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
865 o(0xE8BD0000|todo);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
866 for(i=0;i<4;i++)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
867 if(todo&(1<<i)) {
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
868 vpushi(0);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
869 vtop->r=i;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
870 keep++;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
871 }
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
872 }
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
873 args_size-=n*4;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
874 }
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
875 vnrott(keep);
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
876 func_sym = vtop->type.ref;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
877 gcall_or_jmp(0);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
878 if (args_size)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
879 gadd_sp(args_size);
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
880 #ifdef TCC_ARM_EABI
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
881 if((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
882 && type_size(&vtop->type.ref->type, &align) <= 4)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
883 {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
884 store(REG_IRET,vtop-keep);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
885 ++keep;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
886 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
887 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
888 else if(is_float(vtop->type.ref->type.t)) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
889 if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
890 o(0xEE000A10); /* fmsr s0,r0 */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
891 } else {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
892 o(0xEE000B10); /* fmdlr d0,r0 */
410
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
893 o(0xEE201B10); /* fmdhr d0,r1 */
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
894 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
895 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
896 #endif
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
897 #endif
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
898 vtop-=keep;
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
899 leaffunc = 0;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
900 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
901
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
902 /* generate function prolog of type 't' */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
903 void gfunc_prolog(CType *func_type)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
904 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
905 Sym *sym,*sym2;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
906 int n,addr,size,align;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
907
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
908 sym = func_type->ref;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
909 func_vt = sym->type;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
910
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
911 n = 0;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
912 addr = 0;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
913 if((func_vt.t & VT_BTYPE) == VT_STRUCT
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
914 && type_size(&func_vt,&align) > 4)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
915 {
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
916 func_vc = addr;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
917 addr += 4;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
918 n++;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
919 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
920 for(sym2=sym->next;sym2 && n<4;sym2=sym2->next) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
921 size = type_size(&sym2->type, &align);
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
922 n += (size + 3) / 4;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
923 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
924 o(0xE1A0C00D); /* mov ip,sp */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
925 if(func_type->ref->c == FUNC_ELLIPSIS)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
926 n=4;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
927 if(n) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
928 if(n>4)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
929 n=4;
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
930 #ifdef TCC_ARM_EABI
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
931 n=(n+1)&-2;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
932 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
933 o(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
934 }
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
935 o(0xE92D5800); /* save fp, ip, lr */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
936 o(0xE28DB00C); /* add fp, sp, #12 */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
937 func_sub_sp_offset = ind;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
938 o(0xE1A00000); /* nop, leave space for stack adjustment */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
939 while ((sym = sym->next)) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
940 CType *type;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
941 type = &sym->type;
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
942 size = type_size(type, &align);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
943 size = (size + 3) & -4;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
944 #ifdef TCC_ARM_EABI
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
945 addr = (addr + align - 1) & -align;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
946 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
947 sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
948 addr += size;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
949 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
950 last_itod_magic=0;
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
951 leaffunc = 1;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
952 loc = -12;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
953 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
954
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
955 /* generate function epilog */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
956 void gfunc_epilog(void)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
957 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
958 unsigned long x;
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
959 int diff;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
960 #ifdef TCC_ARM_EABI
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
961 if(is_float(func_vt.t)) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
962 if((func_vt.t & VT_BTYPE) == VT_FLOAT)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
963 o(0xEE100A10); /* fmrs r0, s0 */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
964 else {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
965 o(0xEE100B10); /* fmrdl r0, d0 */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
966 o(0xEE301B10); /* fmrdh r1, d0 */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
967 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
968 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
969 #endif
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
970 o(0xE91BA800); /* restore fp, sp, pc */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
971 diff = (-loc + 3) & -4;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
972 #ifdef TCC_ARM_EABI
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
973 if(!leaffunc)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
974 diff = (diff + 7) & -8;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
975 #endif
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
976 if(diff > 12) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
977 x=stuff_const(0xE24BD000, diff); /* sub sp,fp,# */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
978 if(x)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
979 *(unsigned long *)(cur_text_section->data + func_sub_sp_offset) = x;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
980 else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
981 unsigned long addr;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
982 addr=ind;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
983 o(0xE59FC004); /* ldr ip,[pc+4] */
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
984 o(0xE04BD00C); /* sub sp,fp,ip */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
985 o(0xE1A0F00E); /* mov pc,lr */
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
986 o(diff);
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
987 *(unsigned long *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
988 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
989 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
990 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
991
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
992 /* generate a jump to a label */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
993 int gjmp(int t)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
994 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
995 int r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
996 r=ind;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
997 o(0xE0000000|encbranch(r,t,1));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
998 return r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
999 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1000
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1001 /* generate a jump to a fixed address */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1002 void gjmp_addr(int a)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1003 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1004 gjmp(a);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1005 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1006
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1007 /* generate a test. set 'inv' to invert test. Stack entry is popped */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1008 int gtst(int inv, int t)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1009 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1010 int v, r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1011 unsigned long op;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1012 v = vtop->r & VT_VALMASK;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1013 r=ind;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1014 if (v == VT_CMP) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1015 op=mapcc(inv?negcc(vtop->c.i):vtop->c.i);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1016 op|=encbranch(r,t,1);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1017 o(op);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1018 t=r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1019 } else if (v == VT_JMP || v == VT_JMPI) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1020 if ((v & 1) == inv) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1021 if(!vtop->c.i)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1022 vtop->c.i=t;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1023 else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1024 unsigned long *x;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1025 int p,lp;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1026 if(t) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1027 p = vtop->c.i;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1028 do {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1029 p = decbranch(lp=p);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1030 } while(p);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1031 x = (unsigned long *)(cur_text_section->data + lp);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1032 *x &= 0xff000000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1033 *x |= encbranch(lp,t,1);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1034 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1035 t = vtop->c.i;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1036 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1037 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1038 t = gjmp(t);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1039 gsym(vtop->c.i);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1040 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1041 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1042 if (is_float(vtop->type.t)) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1043 r=gv(RC_FLOAT);
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1044 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1045 o(0xEEB50A40|(vfpr(r)<<12)|T2CPR(vtop->type.t)); /* fcmpzX */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1046 o(0xEEF1FA10); /* fmstat */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1047 #else
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1048 o(0xEE90F118|(fpr(r)<<16));
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1049 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1050 vtop->r = VT_CMP;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1051 vtop->c.i = TOK_NE;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1052 return gtst(inv, t);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1053 } else if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1054 /* constant jmp optimization */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1055 if ((vtop->c.i != 0) != inv)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1056 t = gjmp(t);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1057 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1058 v = gv(RC_INT);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1059 o(0xE3300000|(intr(v)<<16));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1060 vtop->r = VT_CMP;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1061 vtop->c.i = TOK_NE;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1062 return gtst(inv, t);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1063 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1064 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1065 vtop--;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1066 return t;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1067 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1068
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1069 /* generate an integer binary operation */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1070 void gen_opi(int op)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1071 {
337
ab2fa6ee2e59 [project @ 2004-11-07 15:43:15 by bellard]
bellard
parents: 307
diff changeset
1072 int c, func = 0;
ab2fa6ee2e59 [project @ 2004-11-07 15:43:15 by bellard]
bellard
parents: 307
diff changeset
1073 unsigned long opc = 0,r,fr;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1074
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1075 c=0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1076 switch(op) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1077 case '+':
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1078 opc = 0x8;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1079 c=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1080 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1081 case TOK_ADDC1: /* add with carry generation */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1082 opc = 0x9;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1083 c=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1084 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1085 case '-':
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1086 opc = 0x4;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1087 c=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1088 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1089 case TOK_SUBC1: /* sub with carry generation */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1090 opc = 0x5;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1091 c=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1092 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1093 case TOK_ADDC2: /* add with carry use */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1094 opc = 0xA;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1095 c=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1096 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1097 case TOK_SUBC2: /* sub with carry use */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1098 opc = 0xC;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1099 c=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1100 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1101 case '&':
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1102 opc = 0x0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1103 c=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1104 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1105 case '^':
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1106 opc = 0x2;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1107 c=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1108 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1109 case '|':
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1110 opc = 0x18;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1111 c=1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1112 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1113 case '*':
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1114 gv2(RC_INT, RC_INT);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1115 r = vtop[-1].r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1116 fr = vtop[0].r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1117 vtop--;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1118 o(0xE0000090|(intr(r)<<16)|(intr(r)<<8)|intr(fr));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1119 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1120 case TOK_SHL:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1121 opc = 0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1122 c=2;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1123 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1124 case TOK_SHR:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1125 opc = 1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1126 c=2;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1127 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1128 case TOK_SAR:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1129 opc = 2;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1130 c=2;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1131 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1132 case '/':
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1133 case TOK_PDIV:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1134 func=TOK___divsi3;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1135 c=3;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1136 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1137 case TOK_UDIV:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1138 func=TOK___udivsi3;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1139 c=3;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1140 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1141 case '%':
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1142 func=TOK___modsi3;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1143 c=3;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1144 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1145 case TOK_UMOD:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1146 func=TOK___umodsi3;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1147 c=3;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1148 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1149 case TOK_UMULL:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1150 gv2(RC_INT, RC_INT);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1151 r=intr(vtop[-1].r2=get_reg(RC_INT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1152 c=vtop[-1].r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1153 vtop[-1].r=get_reg_ex(RC_INT,regmask(c));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1154 vtop--;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1155 o(0xE0800090|(r<<16)|(intr(vtop->r)<<12)|(intr(c)<<8)|intr(vtop[1].r));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1156 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1157 default:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1158 opc = 0x15;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1159 c=1;
337
ab2fa6ee2e59 [project @ 2004-11-07 15:43:15 by bellard]
bellard
parents: 307
diff changeset
1160 break;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1161 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1162 switch(c) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1163 case 1:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1164 if((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1165 if(opc == 4 || opc == 5 || opc == 0xc) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1166 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1167 opc|=2; // sub -> rsb
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1168 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1169 }
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1170 if ((vtop->r & VT_VALMASK) == VT_CMP ||
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1171 (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1172 gv(RC_INT);
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1173 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1174 c=intr(gv(RC_INT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1175 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1176 opc=0xE0000000|(opc<<20)|(c<<16);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1177 if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1178 unsigned long x;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1179 x=stuff_const(opc|0x2000000,vtop->c.i);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1180 if(x) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1181 r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1182 o(x|(r<<12));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1183 goto done;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1184 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1185 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1186 fr=intr(gv(RC_INT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1187 r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1188 o(opc|(r<<12)|fr);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1189 done:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1190 vtop--;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1191 if (op >= TOK_ULT && op <= TOK_GT) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1192 vtop->r = VT_CMP;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1193 vtop->c.i = op;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1194 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1195 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1196 case 2:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1197 opc=0xE1A00000|(opc<<5);
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1198 if ((vtop->r & VT_VALMASK) == VT_CMP ||
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1199 (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1200 gv(RC_INT);
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1201 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1202 r=intr(gv(RC_INT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1203 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1204 opc|=r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1205 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1206 fr=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1207 c = vtop->c.i & 0x1f;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1208 o(opc|(c<<7)|(fr<<12));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1209 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1210 fr=intr(gv(RC_INT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1211 c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1212 o(opc|(c<<12)|(fr<<8)|0x10);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1213 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1214 vtop--;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1215 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1216 case 3:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1217 vpush_global_sym(&func_old_type, func);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1218 vrott(3);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1219 gfunc_call(2);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1220 vpushi(0);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1221 vtop->r = REG_IRET;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1222 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1223 default:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1224 error("gen_opi %i unimplemented!",op);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1225 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1226 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1227
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1228 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1229 static int is_zero(int i)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1230 {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1231 if((vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1232 return 0;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1233 if (vtop[i].type.t == VT_FLOAT)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1234 return (vtop[i].c.f == 0.f);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1235 else if (vtop[i].type.t == VT_DOUBLE)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1236 return (vtop[i].c.d == 0.0);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1237 return (vtop[i].c.ld == 0.l);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1238 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1239
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1240 /* generate a floating point operation 'v = t1 op t2' instruction. The
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1241 * two operands are guaranted to have the same floating point type */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1242 void gen_opf(int op)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1243 {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1244 unsigned long x;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1245 int fneg=0,r;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1246 x=0xEE000A00|T2CPR(vtop->type.t);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1247 switch(op) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1248 case '+':
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1249 if(is_zero(-1))
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1250 vswap();
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1251 if(is_zero(0)) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1252 vtop--;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1253 return;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1254 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1255 x|=0x300000;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1256 break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1257 case '-':
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1258 x|=0x300040;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1259 if(is_zero(0)) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1260 vtop--;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1261 return;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1262 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1263 if(is_zero(-1)) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1264 x|=0x810000; /* fsubX -> fnegX */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1265 vswap();
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1266 vtop--;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1267 fneg=1;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1268 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1269 break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1270 case '*':
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1271 x|=0x200000;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1272 break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1273 case '/':
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1274 x|=0x800000;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1275 break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1276 default:
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1277 if(op < TOK_ULT && op > TOK_GT) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1278 error("unknown fp op %x!",op);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1279 return;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1280 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1281 if(is_zero(-1)) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1282 vswap();
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1283 switch(op) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1284 case TOK_LT: op=TOK_GT; break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1285 case TOK_GE: op=TOK_ULE; break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1286 case TOK_LE: op=TOK_GE; break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1287 case TOK_GT: op=TOK_ULT; break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1288 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1289 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1290 x|=0xB40040; /* fcmpX */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1291 if(op!=TOK_EQ && op!=TOK_NE)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1292 x|=0x80; /* fcmpX -> fcmpeX */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1293 if(is_zero(0)) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1294 vtop--;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1295 o(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1296 } else {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1297 x|=vfpr(gv(RC_FLOAT));
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1298 vswap();
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1299 o(x|(vfpr(gv(RC_FLOAT))<<12));
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1300 vtop--;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1301 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1302 o(0xEEF1FA10); /* fmstat */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1303
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1304 switch(op) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1305 case TOK_LE: op=TOK_ULE; break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1306 case TOK_LT: op=TOK_ULT; break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1307 case TOK_UGE: op=TOK_GE; break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1308 case TOK_UGT: op=TOK_GT; break;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1309 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1310
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1311 vtop->r = VT_CMP;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1312 vtop->c.i = op;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1313 return;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1314 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1315 r=gv(RC_FLOAT);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1316 x|=vfpr(r);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1317 r=regmask(r);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1318 if(!fneg) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1319 int r2;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1320 vswap();
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1321 r2=gv(RC_FLOAT);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1322 x|=vfpr(r2)<<16;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1323 r|=regmask(r2);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1324 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1325 vtop->r=get_reg_ex(RC_FLOAT,r);
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1326 if(!fneg)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1327 vtop--;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1328 o(x|(vfpr(vtop->r)<<12));
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1329 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1330
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1331 #else
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1332 static int is_fconst()
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1333 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1334 long double f;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1335 int r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1336 if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1337 return 0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1338 if (vtop->type.t == VT_FLOAT)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1339 f = vtop->c.f;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1340 else if (vtop->type.t == VT_DOUBLE)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1341 f = vtop->c.d;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1342 else
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1343 f = vtop->c.ld;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1344 if(!ieee_finite(f))
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1345 return 0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1346 r=0x8;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1347 if(f<0.0) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1348 r=0x18;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1349 f=-f;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1350 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1351 if(f==0.0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1352 return r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1353 if(f==1.0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1354 return r|1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1355 if(f==2.0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1356 return r|2;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1357 if(f==3.0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1358 return r|3;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1359 if(f==4.0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1360 return r|4;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1361 if(f==5.0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1362 return r|5;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1363 if(f==0.5)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1364 return r|6;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1365 if(f==10.0)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1366 return r|7;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1367 return 0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1368 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1369
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1370 /* generate a floating point operation 'v = t1 op t2' instruction. The
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1371 two operands are guaranted to have the same floating point type */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1372 void gen_opf(int op)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1373 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1374 unsigned long x;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1375 int r,r2,c1,c2;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1376 //fputs("gen_opf\n",stderr);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1377 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1378 c1 = is_fconst();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1379 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1380 c2 = is_fconst();
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1381 x=0xEE000100;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1382 #if LDOUBLE_SIZE == 8
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1383 if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1384 x|=0x80;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1385 #else
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1386 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1387 x|=0x80;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1388 else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1389 x|=0x80000;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1390 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1391 switch(op)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1392 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1393 case '+':
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1394 if(!c2) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1395 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1396 c2=c1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1397 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1398 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1399 r=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1400 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1401 if(c2) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1402 if(c2>0xf)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1403 x|=0x200000; // suf
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1404 r2=c2&0xf;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1405 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1406 r2=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1407 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1408 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1409 case '-':
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1410 if(c2) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1411 if(c2<=0xf)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1412 x|=0x200000; // suf
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1413 r2=c2&0xf;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1414 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1415 r=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1416 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1417 } else if(c1 && c1<=0xf) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1418 x|=0x300000; // rsf
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1419 r2=c1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1420 r=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1421 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1422 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1423 x|=0x200000; // suf
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1424 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1425 r=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1426 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1427 r2=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1428 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1429 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1430 case '*':
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1431 if(!c2 || c2>0xf) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1432 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1433 c2=c1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1434 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1435 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1436 r=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1437 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1438 if(c2 && c2<=0xf)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1439 r2=c2;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1440 else
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1441 r2=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1442 x|=0x100000; // muf
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1443 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1444 case '/':
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1445 if(c2 && c2<=0xf) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1446 x|=0x400000; // dvf
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1447 r2=c2;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1448 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1449 r=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1450 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1451 } else if(c1 && c1<=0xf) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1452 x|=0x500000; // rdf
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1453 r2=c1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1454 r=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1455 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1456 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1457 x|=0x400000; // dvf
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1458 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1459 r=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1460 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1461 r2=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1462 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1463 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1464 default:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1465 if(op >= TOK_ULT && op <= TOK_GT) {
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1466 x|=0xd0f110; // cmfe
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1467 /* bug (intention?) in Linux FPU emulator
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1468 doesn't set carry if equal */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1469 switch(op) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1470 case TOK_ULT:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1471 case TOK_UGE:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1472 case TOK_ULE:
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1473 case TOK_UGT:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1474 error("unsigned comparision on floats?");
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1475 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1476 case TOK_LT:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1477 op=TOK_Nset;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1478 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1479 case TOK_LE:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1480 op=TOK_ULE; /* correct in unordered case only if AC bit in FPSR set */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1481 break;
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1482 case TOK_EQ:
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1483 case TOK_NE:
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1484 x&=~0x400000; // cmfe -> cmf
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1485 break;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1486 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1487 if(c1 && !c2) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1488 c2=c1;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1489 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1490 switch(op) {
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1491 case TOK_Nset:
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1492 op=TOK_GT;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1493 break;
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1494 case TOK_GE:
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1495 op=TOK_ULE;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1496 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1497 case TOK_ULE:
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1498 op=TOK_GE;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1499 break;
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1500 case TOK_GT:
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1501 op=TOK_Nset;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1502 break;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1503 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1504 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1505 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1506 r=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1507 vswap();
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1508 if(c2) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1509 if(c2>0xf)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1510 x|=0x200000;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1511 r2=c2&0xf;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1512 } else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1513 r2=fpr(gv(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1514 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1515 vtop[-1].r = VT_CMP;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1516 vtop[-1].c.i = op;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1517 } else {
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1518 error("unknown fp op %x!",op);
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1519 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1520 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1521 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1522 if(vtop[-1].r == VT_CMP)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1523 c1=15;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1524 else {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1525 c1=vtop->r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1526 if(r2&0x8)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1527 c1=vtop[-1].r;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1528 vtop[-1].r=get_reg_ex(RC_FLOAT,two2mask(vtop[-1].r,c1));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1529 c1=fpr(vtop[-1].r);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1530 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1531 vtop--;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1532 o(x|(r<<16)|(c1<<12)|r2);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1533 }
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1534 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1535
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1536 /* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1537 and 'long long' cases. */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1538 void gen_cvt_itof(int t)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1539 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1540 int r,r2,bt;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1541 bt=vtop->type.t & VT_BTYPE;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1542 if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1543 r=intr(gv(RC_INT));
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1544 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1545 r2=vfpr(vtop->r=get_reg(RC_FLOAT));
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1546 o(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1547 r2<<=12;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1548 if(!(vtop->type.t & VT_UNSIGNED))
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1549 r2|=0x80; /* fuitoX -> fsituX */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1550 o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1551 #else
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1552 r2=fpr(vtop->r=get_reg(RC_FLOAT));
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1553 o(0xEE000190|(r2<<16)|(r<<12));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1554 if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1555 unsigned int off=0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1556 o(0xE3500000|(r<<12));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1557 r=fpr(get_reg(RC_FLOAT));
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1558 if(last_itod_magic) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1559 off=ind+8-last_itod_magic;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1560 off/=4;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1561 if(off>255)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1562 off=0;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1563 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1564 o(0xBD1F8100|(r<<12)|off);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1565 if(!off) {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1566 o(0xEA000001);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1567 last_itod_magic=ind;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1568 o(0x41F00000);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1569 o(0);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1570 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1571 o(0xBE000180|(r2<<16)|(r2<<12)|r);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1572 }
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1573 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1574 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1575 } else if(bt == VT_LLONG) {
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1576 int func;
410
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
1577 CType *func_type = &func_old_type;
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1578 #ifdef TCC_ARM_VFP
410
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
1579 #ifdef TCC_ARM_EABI
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
1580 func_type = &func_double_type;
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
1581 #endif
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1582 if((t & VT_BTYPE) == VT_FLOAT) {
410
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
1583 #ifdef TCC_ARM_EABI
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
1584 func_type = &func_float_type;
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
1585 #endif
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1586 if(vtop->type.t & VT_UNSIGNED)
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1587 func=TOK___ulltof;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1588 else
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1589 func=TOK___slltof;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1590 } else
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1591 #endif
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1592 if(vtop->type.t & VT_UNSIGNED)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1593 func=TOK___ulltold;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1594 else
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1595 func=TOK___slltold;
410
0aada61f9f8d ARM EABI bug fixes from Daniel Glockner.
landley@driftwood
parents: 409
diff changeset
1596 vpush_global_sym(func_type, func);
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1597 vswap();
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1598 gfunc_call(1);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1599 vpushi(0);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1600 vtop->r=TREG_F0;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1601 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1602 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1603 error("unimplemented gen_cvt_itof %x!",vtop->type.t);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1604 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1605
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1606 /* convert fp to int 't' type */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1607 void gen_cvt_ftoi(int t)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1608 {
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1609 int r,r2,u,func=0;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1610 u=t&VT_UNSIGNED;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1611 t&=VT_BTYPE;
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1612 r2=vtop->type.t & VT_BTYPE;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1613 if(t==VT_INT) {
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1614 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1615 r=vfpr(gv(RC_FLOAT));
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1616 u=u?0:0x10000;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1617 o(0xEEBC0A40|(r<<12)|r|T2CPR(r2)); /* ftoXiY */
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1618 r2=intr(vtop->r=get_reg(RC_INT));
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1619 o(0xEE100A10|(r<<16)|(r2<<12));
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1620 return;
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1621 #else
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1622 if(u) {
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1623 if(r2 == VT_FLOAT)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1624 func=TOK___fixunssfsi;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1625 else if(r2 == VT_DOUBLE)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1626 func=TOK___fixunsdfsi;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1627 else if(r2 == VT_LDOUBLE)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1628 #if LDOUBLE_SIZE == 8
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1629 func=TOK___fixunsdfsi;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1630 #else
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1631 func=TOK___fixunsxfsi;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1632 #endif
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1633 } else {
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1634 r=fpr(gv(RC_FLOAT));
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1635 r2=intr(vtop->r=get_reg(RC_INT));
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1636 o(0xEE100170|(r2<<12)|r);
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1637 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1638 }
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1639 #endif
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1640 } else if(t == VT_LLONG) { // unsigned handled in gen_cvt_ftoi1
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1641 if(r2 == VT_FLOAT)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1642 func=TOK___fixsfdi;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1643 else if(r2 == VT_DOUBLE)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1644 func=TOK___fixdfdi;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1645 else if(r2 == VT_LDOUBLE)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1646 #if LDOUBLE_SIZE == 8
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1647 func=TOK___fixdfdi;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1648 #else
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1649 func=TOK___fixxfdi;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1650 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1651 }
307
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1652 if(func) {
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1653 vpush_global_sym(&func_old_type, func);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1654 vswap();
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1655 gfunc_call(1);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1656 vpushi(0);
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1657 if(t == VT_LLONG)
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1658 vtop->r2 = REG_LRET;
1e5313e0e93b [project @ 2004-10-04 22:19:21 by bellard]
bellard
parents: 305
diff changeset
1659 vtop->r = REG_IRET;
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1660 return;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1661 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1662 error("unimplemented gen_cvt_ftoi!");
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1663 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1664
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1665 /* convert from one floating point type to another */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1666 void gen_cvt_ftof(int t)
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1667 {
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1668 #ifdef TCC_ARM_VFP
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1669 if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1670 int r=vfpr(gv(RC_FLOAT));
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1671 o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t));
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1672 }
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1673 #else
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1674 /* all we have to do on i386 and FPA ARM is to put the float in a register */
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1675 gv(RC_FLOAT);
409
41f19a7b4093 Support for ARM EABI, by Daniel Glockner.
landley@driftwood
parents: 337
diff changeset
1676 #endif
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1677 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1678
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1679 /* computed goto support */
546
3f683703c8db Rename ggoto() to gen_goto().
Rob Landley <rob@landley.net>
parents: 509
diff changeset
1680 void gen_goto(void)
295
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1681 {
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1682 gcall_or_jmp(1);
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1683 vtop--;
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1684 }
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1685
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1686 /* end of ARM code generator */
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1687 /*************************************************************/
3a3d42516bbd [project @ 2003-10-14 22:15:56 by bellard]
bellard
parents:
diff changeset
1688