parisc: fix a bug that we tried to generate moves between general
[ajla.git] / c2-hppa.inc
blob2044ae2eaef19cee962fc079b5913a6fbcb03cb9
1 /*
2  * Copyright (C) 2024 Mikulas Patocka
3  *
4  * This file is part of Ajla.
5  *
6  * Ajla is free software: you can redistribute it and/or modify it under the
7  * terms of the GNU General Public License as published by the Free Software
8  * Foundation, either version 3 of the License, or (at your option) any later
9  * version.
10  *
11  * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * Ajla. If not, see <https://www.gnu.org/licenses/>.
17  */
19 #define  PARISC_N                       0x2U
21 #define  PARISC_COND_64                 0x0020U
22 #define  PARISC_COND_NEVER              0x0000U
23 #define  PARISC_COND_ALWAYS             0x1000U
24 #define  PARISC_COND_EQUAL              0x2000U
25 #define  PARISC_COND_NOT_EQUAL          0x3000U
26 #define  PARISC_COND_L_S                0x4000U
27 #define  PARISC_COND_GE_S               0x5000U
28 #define  PARISC_COND_LE_S               0x6000U
29 #define  PARISC_COND_G_S                0x7000U
30 #define  PARISC_COND_L_U                0x8000U
31 #define  PARISC_COND_GE_U               0x9000U
32 #define  PARISC_COND_LE_U               0xa000U
33 #define  PARISC_COND_G_U                0xb000U
34 #define  PARISC_COND_SV                 0xc000U
35 #define  PARISC_COND_NSV                0xd000U
36 #define  PARISC_COND_OD                 0xe000U
37 #define  PARISC_COND_EV                 0xf000U
38 #define  PARISC_COND_NEG                0x1000U
40 #define PARISC_LDSID            0x000010a0U
41 #define PARISC_MTSP             0x00001820U
42 #define PARISC_MTSAR            0x01601840U
43 #define PARISC_MTSARCM          0x016018c0U
44 #define PARISC_ANDCM            0x08000000U
45 #define PARISC_AND              0x08000200U
46 #define PARISC_OR               0x08000240U
47 #define PARISC_NOP              0x08000240U
48 #define PARISC_XOR              0x08000280U
49 #define PARISC_SUB              0x08000400U
50 #define PARISC_SUB_B            0x08000500U
51 #define PARISC_SUB_DB           0x08000520U
52 #define PARISC_ADD              0x08000600U
53 #define PARISC_ADD_C            0x08000700U
54 #define PARISC_ADD_DC           0x08000720U
55 #define PARISC_CMPCLR           0x08000880U
56 #define PARISC_UADDCM           0x08000980U
57 #define PARISC_ADD_L            0x08000a00U
58 #define PARISC_SHLADD_L_1       0x08000a40U
59 #define PARISC_SHLADD_L_2       0x08000a80U
60 #define PARISC_SHLADD_L_3       0x08000ac0U
62 #define PARISC_LD_ST            0x0c000000U
63 #define  PARISC_LD_ST_B                 0x00000000U
64 #define  PARISC_LD_ST_H                 0x00000040U
65 #define  PARISC_LD_ST_W                 0x00000080U
66 #define  PARISC_LD_ST_D                 0x000000c0U
67 #define  PARISC_LD_ST_IMM               0x00001000U
68 #define  PARISC_LD_ST_MA                0x00000020U
69 #define  PARISC_LD_ST_MB                0x00002020U
70 #define  PARISC_LD_ST_LD                0x00000000U
71 #define  PARISC_LD_ST_ST                0x00000200U
72 #define  PARISC_LD_SCALE                0x00002000U
73 #define PARISC_LDIL             0x20000000U
74 #define PARISC_ADDIL            0x28000000U
75 #define PARISC_LDO              0x34000000U
77 #define PARISC_LDB_LONG         0x40000000U
78 #define PARISC_LDH_LONG         0x44000000U
79 #define PARISC_LDW_LONG         0x48000000U
80 #define PARISC_LDW_M            0x4c000000U
81 #define PARISC_LDD              0x50000000U
82 #define PARISC_STB_LONG         0x60000000U
83 #define PARISC_STH_LONG         0x64000000U
84 #define PARISC_STW_LONG         0x68000000U
85 #define PARISC_STW_M            0x6c000000U
86 #define PARISC_STD              0x70000000U
87 #define  PARISC_LDD_STD_MA              0x00000008U
88 #define  PARISC_LDD_STD_MB              0x0000000cU
90 #define PARISC_CMPB             0x80000000U
91 #define PARISC_CMPIB            0x84000000U
92 #define PARISC_CMPB_NOT         0x88000000U
93 #define PARISC_CMPIB_NOT        0x8c000000U
94 #define PARISC_CMPICLR          0x90000000U
95 #define  PARISC_CMPICLR_64              0x00000800U
96 #define PARISC_SUBI             0x94000000U
97 #define PARISC_CMPB_64          0x9c000000U
98 #define PARISC_ADDB             0xa0000000U
99 #define PARISC_ADDB_NOT         0xa8000000U
100 #define PARISC_ADDI             0xb4000000U
101 #define PARISC_CMPB_64_NOT      0xbc000000U
103 #define PARISC_BB_1             0xc4004000U
104 #define PARISC_BB_64_1          0xc4006000U
105 #define PARISC_BB_0             0xc400c000U
106 #define PARISC_BB_64_0          0xc400e000U
107 #define PARISC_SHRPW_SAR        0xd0000000U
108 #define PARISC_SHRPD_SAR        0xd0000200U
109 #define PARISC_EXTRW_U_SAR      0xd0001000U
110 #define PARISC_EXTRD_U_SAR      0xd0001200U
111 #define PARISC_EXTRW_S_SAR      0xd0001400U
112 #define PARISC_EXTRD_S_SAR      0xd0001600U
113 #define PARISC_EXTRW_U          0xd0001800U
114 #define PARISC_EXTRW_S          0xd0001c00U
115 #define PARISC_DEPW_Z_SAR       0xd4000000U
116 #define PARISC_DEPD_Z_SAR       0xd4000200U
117 #define PARISC_DEPW_SAR         0xd4000400U
118 #define PARISC_DEPD_SAR         0xd4000600U
119 #define PARISC_DEPW_Z           0xd4000800U
120 #define PARISC_DEPW             0xd4000c00U
121 #define PARISC_DEPWI_Z_SAR      0xd4001000U
122 #define PARISC_DEPDI_Z_SAR      0xd4001200U
123 #define PARISC_DEPWI_SAR        0xd4001400U
124 #define PARISC_DEPDI_SAR        0xd4001600U
125 #define PARISC_DEPWI_Z          0xd4001800U
126 #define PARISC_DEPWI            0xd4001c00U
127 #define PARISC_EXTRD_U          0xd8001800U
128 #define PARISC_EXTRD_S          0xd8001c00U
129 #define PARISC_BE               0xe0000000U
130 #define PARISC_BL               0xe8000000U
131 #define PARISC_BLR              0xe8004000U
132 #define PARISC_BL_L             0xe800a000U
133 #define PARISC_BV               0xe800c000U
134 #define PARISC_BVE_RET          0xe800d000U
135 #define PARISC_BVE_CALL         0xe800f000U
136 #define PARISC_CMPIB_64         0xec000000U
137 #define PARISC_DEPD_Z           0xf0001000U
138 #define PARISC_DEPD             0xf0001400U
139 #define PARISC_DEPDI_Z          0xf4000000U
140 #define PARISC_DEPDI            0xf4000400U
142 #define  PARISC_FP_DOUBLE               0x00000800U
143 #define PARISC_FLDW             0x24001000U
144 #define PARISC_FSTW             0x24001200U
145 #define PARISC_FLDD             0x2c001000U
146 #define PARISC_FSTD             0x2c001200U
147 #define PARISC_FCMP             0x30000400U
148 #define  PARISC_FCMP_P                  0x02U
149 #define  PARISC_FCMP_NE                 0x04U
150 #define  PARISC_FCMP_AE                 0x08U
151 #define  PARISC_FCMP_A                  0x0cU
152 #define  PARISC_FCMP_BE                 0x10U
153 #define  PARISC_FCMP_B                  0x14U
154 #define  PARISC_FCMP_E                  0x18U
155 #define  PARISC_FCMP_NP                 0x1cU
156 #define PARISC_FADD             0x30000600U
157 #define PARISC_FTEST            0x30002420U
158 #define PARISC_FSUB             0x30002600U
159 #define PARISC_FMPY             0x30004600U
160 #define PARISC_FDIV             0x30006600U
161 #define PARISC_FCNVXF           0x30008200U
162 #define  PARISC_FCNVXF_FROM_LONG        0x00000800U
163 #define  PARISC_FCNVXF_TO_DOUBLE        0x00002000U
164 #define PARISC_FSQRT            0x30008000U
165 #define PARISC_FNEG             0x3000c000U
166 #define PARISC_FCNVFXT          0x30018200U
167 #define  PARISC_FCNVFXT_FROM_DOUBLE     0x00000800U
168 #define  PARISC_FCNVFXT_TO_LONG         0x00002000U
169 #define PARISC_FLDD_LONG        0x50000002U
170 #define PARISC_FLDW_LONG        0x5c000000U
171 #define PARISC_FSTD_LONG        0x70000002U
172 #define PARISC_FSTW_LONG        0x7c000000U
174 static const int32_t cmp_sub_cond[0x12] = {
175         PARISC_COND_SV,         PARISC_COND_NSV,        PARISC_COND_L_U,        PARISC_COND_GE_U,
176         PARISC_COND_EQUAL,      PARISC_COND_NOT_EQUAL,  PARISC_COND_LE_U,       PARISC_COND_G_U,
177         PARISC_COND_L_S,        PARISC_COND_GE_S,       -1,                     -1,
178         PARISC_COND_L_S,        PARISC_COND_GE_S,       PARISC_COND_LE_S,       PARISC_COND_G_S,
179         PARISC_COND_EV,         PARISC_COND_OD,
182 static unsigned cmp_swap_arguments(unsigned cond)
184         switch (cond) {
185                 case COND_B:    return COND_A;
186                 case COND_AE:   return COND_BE;
187                 case COND_E:    return COND_E;
188                 case COND_NE:   return COND_NE;
189                 case COND_BE:   return COND_AE;
190                 case COND_A:    return COND_B;
191                 case COND_L:    return COND_G;
192                 case COND_GE:   return COND_LE;
193                 case COND_LE:   return COND_GE;
194                 case COND_G:    return COND_L;
195         }
196         internal(file_line, "cmp_swap_arguments: can't swap the condition %u", cond);
197         return 0;
200 static bool attr_w cgen_2reg(struct codegen_context *ctx, uint32_t mc, unsigned r1, unsigned rt)
202         mc |= (uint32_t)r1 << 21;
203         mc |= (uint32_t)rt << 16;
204         cgen_four(mc);
205         return true;
208 static bool attr_w cgen_3reg(struct codegen_context *ctx, uint32_t mc, unsigned r1, unsigned r2, unsigned rt)
210         mc |= (uint32_t)r1 << 16;
211         mc |= (uint32_t)r2 << 21;
212         mc |= rt;
213         cgen_four(mc);
214         return true;
217 static uint32_t attr_unused low_sign_ext_5(unsigned bit5)
219         return  ((bit5 & 0x10) >> 4) |
220                 ((bit5 & 0x0f) << 1);
223 static uint32_t low_sign_ext_11(unsigned bit11)
225         return  ((bit11 & 0x400) >> 10) |
226                 ((bit11 & 0x3ff) << 1);
229 static uint32_t low_sign_ext_14(unsigned bit14)
231         return  ((bit14 & 0x2000) >> 13) |
232                 ((bit14 & 0x1fff) << 1);
235 static uint32_t assemble_12(uint32_t bit12)
237         return  ((bit12 & 0x800) >> 11) |
238                 ((bit12 & 0x400) >> 8) |
239                 ((bit12 & 0x3ff) << 3);
242 static uint32_t assemble_17(uint32_t bit17)
244         return  ((bit17 & 0x10000) >> 16) |
245                 ((bit17 & 0x0f800) << 5) |
246                 ((bit17 & 0x00400) >> 8) |
247                 ((bit17 & 0x003ff) << 3);
250 static uint32_t assemble_21(uint32_t bit21)
252         return  ((bit21 & 0x100000) >> 20) |
253                 ((bit21 & 0x0ffe00) >> 8) |
254                 ((bit21 & 0x000180) << 7) |
255                 ((bit21 & 0x00007c) << 14) |
256                 ((bit21 & 0x000003) << 12);
259 static uint32_t assemble_22(uint32_t bit22)
261         return  ((bit22 & 0x200000) >> 21) |
262                 ((bit22 & 0x1f0000) << 5) |
263                 ((bit22 & 0x00f800) << 5) |
264                 ((bit22 & 0x000400) >> 8) |
265                 ((bit22 & 0x0003ff) << 3);
268 static bool attr_w cgen_ret(struct codegen_context *ctx)
270         uint32_t mc;
271         if (!PA_20 && PA_SPACES) {
272                 mc = PARISC_LDSID;
273                 mc |= (uint32_t)R_RP << 21;
274                 mc |= R_CG_SCRATCH;
275                 cgen_four(mc);
276                 mc = PARISC_MTSP;
277                 mc |= (uint32_t)R_CG_SCRATCH << 16;
278                 cgen_four(mc);
279                 mc = PARISC_BE;
280                 mc |= (uint32_t)R_RP << 21;
281                 mc |= PARISC_N;
282                 cgen_four(mc);
283         } else {
284                 mc = PA_20 ? PARISC_BVE_RET : PARISC_BV;
285                 mc |= (uint32_t)R_RP << 21;
286                 mc |= PARISC_N;
287                 cgen_four(mc);
288         }
289         cgen_four(PARISC_NOP);
290         return true;
293 static bool attr_w cgen_call(struct codegen_context *ctx, unsigned length)
295         if (length <= JMP_SHORT) {
296                 g(add_relocation(ctx, JMP_SHORT, 0, NULL));
297                 cgen_four(PARISC_BL | ((uint32_t)R_RP << 21) | PARISC_N);
298                 cgen_four(PARISC_NOP);
299         } else if (length == JMP_LONG && PA_20) {
300                 g(add_relocation(ctx, JMP_LONG, 0, NULL));
301                 cgen_four(PARISC_BL_L | PARISC_N);
302                 cgen_four(PARISC_NOP);
303         } else {
304                 g(add_relocation(ctx, JMP_EXTRA_LONG, 0, NULL));
305                 cgen_four(PARISC_LDIL | ((uint32_t)R_CG_SCRATCH << 21));
306                 g(cgen_2reg(ctx, PARISC_LDO, R_CG_SCRATCH, R_CG_SCRATCH));
307                 g(cgen_2reg(ctx, PARISC_BLR | PARISC_N, R_RP, R_CG_SCRATCH));
308                 g(cgen_2reg(ctx, PARISC_BLR | PARISC_N, R_RP, R_CG_SCRATCH));
309                 cgen_four(PARISC_NOP);
310         }
311         return true;
314 static bool attr_w cgen_call_indirect(struct codegen_context *ctx)
316         uint32_t mc;
317         unsigned reg = cget_one(ctx);
319         mc = PARISC_LDD | low_sign_ext_14(0x10);
320         g(cgen_2reg(ctx, mc, reg, R_31));
322         cgen_four(PARISC_BVE_CALL | ((uint32_t)R_31 << 21));
324         mc = PARISC_LDD | low_sign_ext_14(0x18);
325         g(cgen_2reg(ctx, mc, reg, R_DP));
327         return true;
330 static bool attr_w cgen_ld_st(struct codegen_context *ctx, bool ld, unsigned size, uint8_t reg, uint8_t *address)
332         int64_t imm = 0;
333         uint32_t mc;
335         if (address[0] == ARG_ADDRESS_1) {
336                 imm = get_imm(&address[2]);
337                 if (ld) {
338                         switch (size) {
339                                 case OP_SIZE_1: mc = PARISC_LDB_LONG; break;
340                                 case OP_SIZE_2: mc = PARISC_LDH_LONG; break;
341                                 case OP_SIZE_4: mc = PARISC_LDW_LONG; break;
342                                 case OP_SIZE_8: mc = PARISC_LDD; break;
343                                 default:        goto invalid;
344                         }
345                 } else {
346                         switch (size) {
347                                 case OP_SIZE_1: mc = PARISC_STB_LONG; break;
348                                 case OP_SIZE_2: mc = PARISC_STH_LONG; break;
349                                 case OP_SIZE_4: mc = PARISC_STW_LONG; break;
350                                 case OP_SIZE_8: mc = PARISC_STD; break;
351                                 default:        goto invalid;
352                         }
353                 }
354                 mc |= low_sign_ext_14(imm);
355                 g(cgen_2reg(ctx, mc, address[1], reg));
356                 return true;
357         }
358         if (address[0] == ARG_ADDRESS_1_PRE_I || address[0] == ARG_ADDRESS_1_POST_I) {
359                 imm = get_imm(&address[2]);
360                 if (size == OP_SIZE_4) {
361                         if (imm >= 0 && address[0] == ARG_ADDRESS_1_PRE_I)
362                                 goto invalid;
363                         if (imm < 0 && address[0] == ARG_ADDRESS_1_POST_I)
364                                 goto invalid;
365                 }
366                 if (ld) {
367                         switch (size) {
368                                 case OP_SIZE_4: mc = PARISC_LDW_M; break;
369                                 case OP_SIZE_8: mc = PARISC_LDD | (address[0] == ARG_ADDRESS_1_PRE_I ? PARISC_LDD_STD_MB : PARISC_LDD_STD_MA); break;
370                                 default:        goto invalid;
371                         }
372                 } else {
373                         switch (size) {
374                                 case OP_SIZE_4: mc = PARISC_STW_M; break;
375                                 case OP_SIZE_8: mc = PARISC_STD | (address[0] == ARG_ADDRESS_1_PRE_I ? PARISC_LDD_STD_MB : PARISC_LDD_STD_MA); break;
376                                 default:        goto invalid;
377                         }
378                 }
379                 mc |= low_sign_ext_14(imm);
380                 g(cgen_2reg(ctx, mc, address[1], reg));
381                 return true;
382         }
383         if (address[0] >= ARG_ADDRESS_2 && address[0] <= ARG_ADDRESS_2_8 && ld) {
384                 imm = get_imm(&address[3]);
385                 if (unlikely(imm != 0))
386                         goto invalid;
387                 mc = PARISC_LD_ST | PARISC_LD_ST_LD;
388                 if (address[0] == ARG_ADDRESS_2) {
389                 } else if (address[0] == ARG_ADDRESS_2_4 && size == OP_SIZE_4) {
390                         mc |= PARISC_LD_SCALE;
391                 } else if (address[0] == ARG_ADDRESS_2_8 && size == OP_SIZE_8) {
392                         mc |= PARISC_LD_SCALE;
393                 } else {
394                         goto invalid;
395                 }
396                 switch (size) {
397                         case OP_SIZE_1: mc |= PARISC_LD_ST_B; break;
398                         case OP_SIZE_2: mc |= PARISC_LD_ST_H; break;
399                         case OP_SIZE_4: mc |= PARISC_LD_ST_W; break;
400                         case OP_SIZE_8: mc |= PARISC_LD_ST_D; break;
401                         default:        goto invalid;
402                 }
403                 g(cgen_3reg(ctx, mc, address[2], address[1], reg));
404                 return true;
405         }
406 invalid:
407         internal(file_line, "cgen_ld_st: invalid address: %x, %02x, %02x, %"PRIxMAX"", size, reg, address[0], (uintmax_t)imm);
408         return false;
411 static bool attr_w cgen_fp_ld_st(struct codegen_context *ctx, bool ld, unsigned size, uint8_t reg, uint8_t *address)
413         int64_t imm = 0;
414         uint32_t mc;
416         if (unlikely(address[0] != ARG_ADDRESS_1))
417                 goto invalid;
419         imm = get_imm(&address[2]);
420         if (imm >= -0x10 && imm < 0x10) {
421                 if (ld)
422                         mc = size == OP_SIZE_4 ? PARISC_FLDW : PARISC_FLDD;
423                 else
424                         mc = size == OP_SIZE_4 ? PARISC_FSTW : PARISC_FSTD;
425                 mc |= low_sign_ext_5(imm) << 16;
426                 mc |= reg & 0x1f;
427                 mc |= (uint32_t)address[1] << 21;
428                 cgen_four(mc);
429                 return true;
430         } else {
431                 if (ld)
432                         mc = size == OP_SIZE_4 ? PARISC_FLDW_LONG : PARISC_FLDD_LONG;
433                 else
434                         mc = size == OP_SIZE_4 ? PARISC_FSTW_LONG : PARISC_FSTD_LONG;
435                 mc |= low_sign_ext_14(imm);
436                 g(cgen_2reg(ctx, mc, address[1], reg & 0x1f));
437                 return true;
438         }
440 invalid:
441         internal(file_line, "cgen_fp_ld_st: invalid address: %x, %02x, %02x, %"PRIxMAX"", size, reg, address[0], (uintmax_t)imm);
442         return false;
445 static bool attr_w cgen_mov_args(struct codegen_context *ctx, unsigned size, uint8_t *arg1, uint8_t *arg2)
447         int64_t imm;
448         uint32_t mc;
450         if (arg1[0] < 0x20) {
451                 if (arg2[0] < 0x20) {
452                         if (size < OP_SIZE_NATIVE) {
453                                 if (OP_SIZE_NATIVE == OP_SIZE_4) {
454                                         switch (size) {
455                                                 case OP_SIZE_1:
456                                                         mc = PARISC_EXTRW_U ^ 0x3f8U;
457                                                         break;
458                                                 case OP_SIZE_2:
459                                                         mc = PARISC_EXTRW_U ^ 0x3f0U;
460                                                         break;
461                                                 default:
462                                                         internal(file_line, "cgen_mov_args: invalid op size %u", size);
463                                         }
464                                 } else {
465                                         switch (size) {
466                                                 case OP_SIZE_1:
467                                                         mc = PARISC_EXTRD_U ^ 0x13f8U;
468                                                         break;
469                                                 case OP_SIZE_2:
470                                                         mc = PARISC_EXTRD_U ^ 0x13f0U;
471                                                         break;
472                                                 case OP_SIZE_4:
473                                                         mc = PARISC_EXTRD_U ^ 0x13e0U;
474                                                         break;
475                                                 default:
476                                                         internal(file_line, "cgen_mov_args: invalid op size %u", size);
477                                         }
478                                 }
479                                 g(cgen_2reg(ctx, mc, arg2[0], arg1[0]));
480                                 return true;
481                         }
482                         g(cgen_3reg(ctx, PARISC_OR, arg2[0], 0, arg1[0]));
483                         return true;
484                 }
485                 if (arg2[0] == ARG_IMM) {
486                         imm = get_imm(&arg2[1]);
487                         if (imm >= -0x2000 && imm < 0x2000) {
488                                 mc = PARISC_LDO;
489                                 mc |= low_sign_ext_14(imm);
490                                 g(cgen_2reg(ctx, mc, R_ZERO, arg1[0]));
491                                 return true;
492                         }
493                         if (imm & 0x7ff)
494                                 goto invalid;
495                         mc = PARISC_LDIL;
496                         mc |= (uint32_t)arg1[0] << 21;
497                         mc |= assemble_21((uint64_t)imm >> 11);
498                         cgen_four(mc);
499                         return true;
500                 }
501                 return cgen_ld_st(ctx, true, size, arg1[0], arg2);
502         }
504         if (arg2[0] < 0x20) {
505                 return cgen_ld_st(ctx, false, size, arg2[0], arg1);
506         }
507         if (arg2[0] == ARG_IMM) {
508                 imm = get_imm(&arg2[1]);
509                 if (unlikely(imm != 0))
510                         goto invalid;
511                 return cgen_ld_st(ctx, false, size, R_ZERO, arg1);
512         }
514         if (reg_is_fp(arg1[0]) && arg2[0] == ARG_ADDRESS_1) {
515                 return cgen_fp_ld_st(ctx, true, size, arg1[0], arg2);
516         }
517         if (reg_is_fp(arg2[0]) && arg1[0] == ARG_ADDRESS_1) {
518                 return cgen_fp_ld_st(ctx, false, size, arg2[0], arg1);
519         }
521 invalid:
522         internal(file_line, "cgen_mov_args: invalid arguments %02x, %02x", arg1[0], arg2[0]);
523         return false;
526 static bool attr_w cgen_mov(struct codegen_context *ctx, unsigned size)
528         uint8_t *arg1 = ctx->code_position;
529         uint8_t *arg2 = arg1 + arg_size(*arg1);
530         ctx->code_position = arg2 + arg_size(*arg2);
531         return cgen_mov_args(ctx, size, arg1, arg2);
534 static bool attr_w cgen_movsx(struct codegen_context *ctx, unsigned size)
536         uint32_t mc;
537         uint8_t *arg1 = ctx->code_position;
538         uint8_t *arg2 = arg1 + arg_size(*arg1);
539         ctx->code_position = arg2 + arg_size(*arg2);
540         if (unlikely(arg1[0] >= 0x20) || unlikely(arg2[0] >= 0x20))
541                 internal(file_line, "cgen_movsx: invalid arguments %02x, %02x", arg1[0], arg2[0]);
543         if (size < OP_SIZE_NATIVE) {
544                 if (OP_SIZE_NATIVE == OP_SIZE_4) {
545                         switch (size) {
546                                 case OP_SIZE_1:
547                                         mc = PARISC_EXTRW_S ^ 0x3f8U;
548                                         break;
549                                 case OP_SIZE_2:
550                                         mc = PARISC_EXTRW_S ^ 0x3f0U;
551                                         break;
552                                 default:
553                                         internal(file_line, "cgen_movsx: invalid op size %u", size);
554                         }
555                 } else {
556                         switch (size) {
557                                 case OP_SIZE_1:
558                                         mc = PARISC_EXTRD_S ^ 0x13f8U;
559                                         break;
560                                 case OP_SIZE_2:
561                                         mc = PARISC_EXTRD_S ^ 0x13f0U;
562                                         break;
563                                 case OP_SIZE_4:
564                                         mc = PARISC_EXTRD_S ^ 0x13e0U;
565                                         break;
566                                 default:
567                                         internal(file_line, "cgen_movsx: invalid op size %u", size);
568                         }
569                 }
570                 g(cgen_2reg(ctx, mc, arg2[0], arg1[0]));
571                 return true;
572         } else {
573                 return cgen_mov_args(ctx, size, arg1, arg2);
574         }
577 static bool attr_w cgen_cmp_dest_reg(struct codegen_context *ctx, unsigned size, unsigned cond)
579         int32_t fc;
580         uint32_t mc;
581         uint8_t *arg1 = ctx->code_position;
582         uint8_t *arg2 = arg1 + arg_size(*arg1);
583         uint8_t *arg3 = arg2 + arg_size(*arg2);
584         ctx->code_position = arg3 + arg_size(*arg3);
586         if (arg3[0] == ARG_IMM) {
587                 cond = cmp_swap_arguments(cond);
588         }
590         fc = cmp_sub_cond[cond];
591         fc ^= PARISC_COND_NEG;
593         if (arg3[0] == ARG_IMM) {
594                 int64_t imm = get_imm(&arg3[1]);
595                 mc = PARISC_CMPICLR;
596                 if (size == OP_SIZE_8)
597                         mc |= PARISC_CMPICLR_64;
598                 mc |= fc;
599                 mc |= low_sign_ext_11(imm);
600                 g(cgen_2reg(ctx, mc, arg2[0], arg1[0]));
601         } else {
602                 mc = PARISC_CMPCLR;
603                 if (size == OP_SIZE_8)
604                         mc |= PARISC_COND_64;
605                 mc |= fc;
606                 g(cgen_3reg(ctx, mc, arg2[0], arg3[0], arg1[0]));
607         }
609         mc = PARISC_LDO;
610         mc |= low_sign_ext_14(1);
611         g(cgen_2reg(ctx, mc, R_ZERO, arg1[0]));
613         return true;
616 static bool attr_w cgen_alu(struct codegen_context *ctx, unsigned size, unsigned writes_flags, unsigned alu, bool trap, unsigned length)
618         uint32_t mc;
619         uint8_t *arg1 = ctx->code_position;
620         uint8_t *arg2 = arg1 + arg_size(*arg1);
621         uint8_t *arg3 = arg2 + arg_size(*arg2);
622         ctx->code_position = arg3 + arg_size(*arg3);
624         if (unlikely(arg1[0] >= 0x20) || unlikely(arg2[0] >= 0x20))
625                 goto invalid;
627         if (arg3[0] == ARG_IMM && !trap) {
628                 int64_t imm = get_imm(&arg3[1]);
629                 if (unlikely(writes_flags))
630                         goto invalid;
631                 switch (alu) {
632                         case ALU_SUB:
633                                 imm = -(uint64_t)imm;
634                                 /*-fallthrough*/
635                         case ALU_ADD:
636                                 if (imm >= -0x2000 && imm < 0x2000) {
637                                         mc = PARISC_LDO;
638                                         mc |= low_sign_ext_14(imm);
639                                         g(cgen_2reg(ctx, mc, arg2[0], arg1[0]));
640                                         return true;
641                                 } else if (!(imm & 0x7ff) && arg1[0] == R_1) {
642                                         mc = PARISC_ADDIL;
643                                         mc |= (uint32_t)arg2[0] << 21;
644                                         mc |= assemble_21((uint64_t)imm >> 11);
645                                         cgen_four(mc);
646                                         return true;
647                                 } else {
648                                         goto invalid;
649                                 }
650                         default:
651                                 goto invalid;
652                 }
653         }
655         switch (alu) {
656                 case ALU_ADD:   mc = writes_flags ? PARISC_ADD : PARISC_ADD_L;
657                                 break;
658                 case ALU_OR:    ajla_assert_lo(!writes_flags, (file_line, "cgen_alu: or must not write flags"));
659                                 mc = PARISC_OR;
660                                 break;
661                 case ALU_ADC:   ajla_assert_lo(writes_flags, (file_line, "cgen_alu: adc must write flags"));
662                                 mc = size == OP_SIZE_4 ? PARISC_ADD_C : PARISC_ADD_DC;
663                                 break;
664                 case ALU_SBB:   ajla_assert_lo(writes_flags, (file_line, "cgen_alu: sbb must write flags"));
665                                 mc = size == OP_SIZE_4 ? PARISC_SUB_B : PARISC_SUB_DB;
666                                 break;
667                 case ALU_AND:   ajla_assert_lo(!writes_flags, (file_line, "cgen_alu: and must not write flags"));
668                                 mc = PARISC_AND;
669                                 break;
670                 case ALU_SUB:   ajla_assert_lo(writes_flags, (file_line, "cgen_alu: sub must write flags"));
671                                 mc = PARISC_SUB;
672                                 break;
673                 case ALU_XOR:   ajla_assert_lo(!writes_flags, (file_line, "cgen_alu: xor must not write flags"));
674                                 mc = PARISC_XOR;
675                                 break;
676                 case ALU_ANDN:  ajla_assert_lo(!writes_flags, (file_line, "cgen_alu: andn must not write flags"));
677                                 mc = PARISC_ANDCM;
678                                 break;
679                 default:        goto invalid;
680         }
682         if (alu == ALU_ADD && arg3[0] == ARG_SHIFTED_REGISTER) {
683                 uint8_t *args;
684                 if (unlikely((arg3[1] >> 6) != 0))
685                         goto invalid;
686                 if (unlikely((arg3[1] & ARG_SHIFT_AMOUNT)) >= 4)
687                         goto invalid;
688                 mc |= (uint32_t)(arg3[1] & ARG_SHIFT_AMOUNT) << 6;
689                 arg3 += 2;
690                 args = arg3;
691                 arg3 = arg2;
692                 arg2 = args;
693         }
695         if (unlikely(arg3[0] >= 0x20))
696                 goto invalid;
698 #ifdef ARCH_PARISC32
699         if (alu == ALU_ADD && size == OP_SIZE_4 && arg1[0] == arg2[0] && trap && length == JMP_SHORTEST) {
700                 bool need_nop;
701                 mc = PARISC_ADDB;
702                 mc |= PARISC_COND_SV;
703                 mc |= PARISC_N;
704                 g(add_relocation(ctx, JMP_SHORTEST, ctx->code_position - arg1, &need_nop));
705                 g(cgen_2reg(ctx, mc, arg1[0], arg3[0]));
706                 if (unlikely(need_nop))
707                         cgen_four(PARISC_NOP);
708                 return true;
709         }
710 #endif
712         if (trap) {
713                 if (length == JMP_EXTRA_LONG || (length == JMP_LONG && !PA_20))
714                         mc |= PARISC_COND_SV;
715                 else
716                         mc |= PARISC_COND_NSV;
717                 if (size == OP_SIZE_8)
718                         mc |= PARISC_COND_64;
719         }
721         g(cgen_3reg(ctx, mc, arg2[0], arg3[0], arg1[0]));
723         if (trap) {
724                 if (length <= JMP_SHORT) {
725                         g(add_relocation(ctx, JMP_SHORT, ctx->code_position - arg1, NULL));
726                         cgen_four(PARISC_BL | PARISC_N);
727                 } else if (length == JMP_LONG && PA_20) {
728                         g(add_relocation(ctx, JMP_LONG, ctx->code_position - arg1, NULL));
729                         cgen_four(PARISC_BL_L | PARISC_N);
730                 } else {
731                         cgen_four(PARISC_BL | PARISC_N | assemble_12(3));
732                         g(add_relocation(ctx, JMP_EXTRA_LONG, ctx->code_position - arg1, NULL));
733                         cgen_four(PARISC_LDIL | ((uint32_t)R_CG_SCRATCH << 21));
734                         g(cgen_2reg(ctx, PARISC_LDO, R_CG_SCRATCH, R_CG_SCRATCH));
735                         g(cgen_2reg(ctx, PARISC_BLR | PARISC_N, R_ZERO, R_CG_SCRATCH));
736                         g(cgen_2reg(ctx, PARISC_BLR | PARISC_N, R_ZERO, R_CG_SCRATCH));
737                 }
738         }
740         return true;
742 invalid:
743         internal(file_line, "cgen_alu: invalid arguments %02x, %02x, %02x, %u, %u", arg1[0], arg2[0], arg3[0], alu, writes_flags);
744         return false;
747 static bool attr_w cgen_alu1(struct codegen_context *ctx, unsigned size, unsigned writes_flags, unsigned alu, bool trap, unsigned length)
749         uint32_t mc;
750         unsigned r1, r2, rt;
751         uint8_t *arg1 = ctx->code_position;
752         uint8_t *arg2 = arg1 + arg_size(*arg1);
753         ctx->code_position = arg2 + arg_size(*arg2);
755         if (unlikely(arg1[0] >= 0x20) || unlikely(arg2[0] >= 0x20))
756                 goto invalid;
758         switch (alu) {
759                 case ALU1_NOT:  ajla_assert_lo(!writes_flags, (file_line, "cgen_alu1: not must not write flags"));
760                                 mc = PARISC_UADDCM;
761                                 r1 = R_ZERO;
762                                 r2 = arg2[0];
763                                 rt = arg1[0];
764                                 break;
765                 case ALU1_NEG:  ajla_assert_lo(writes_flags, (file_line, "cgen_alu1: neg must write flags"));
766                                 mc = PARISC_SUB;
767                                 r1 = R_ZERO;
768                                 r2 = arg2[0];
769                                 rt = arg1[0];
770                                 break;
771                 case ALU1_INC:
772                 case ALU1_DEC:  ajla_assert_lo(writes_flags, (file_line, "cgen_alu1: inc/dec must write flags"));
773                                 if (trap && size == OP_SIZE_8) {
774                                         mc = PARISC_LDO;
775                                         mc |= low_sign_ext_14(alu == ALU1_INC ? 1 : -1);
776                                         g(cgen_2reg(ctx, mc, R_ZERO, R_CG_SCRATCH));
778                                         mc = PARISC_ADD;
779                                         r1 = arg2[0];
780                                         r2 = R_CG_SCRATCH;
781                                         rt = arg1[0];
782                                 } else {
783                                         mc = PARISC_ADDI;
784                                         mc |= low_sign_ext_11(alu == ALU1_INC ? 1 : -1);
785                                         r1 = arg2[0];
786                                         r2 = arg1[0];
787                                         rt = 0;
788                                 }
789                                 break;
790                 default:        goto invalid;
791         }
793         if (trap) {
794                 if (length == JMP_EXTRA_LONG || (length == JMP_LONG && !PA_20))
795                         mc |= PARISC_COND_SV;
796                 else
797                         mc |= PARISC_COND_NSV;
798                 if (size == OP_SIZE_8)
799                         mc |= PARISC_COND_64;
800         }
802         g(cgen_3reg(ctx, mc, r1, r2, rt));
804         if (trap) {
805                 if (length <= JMP_SHORT) {
806                         g(add_relocation(ctx, JMP_SHORT, ctx->code_position - arg1, NULL));
807                         cgen_four(PARISC_BL | PARISC_N);
808                 } else if (length == JMP_LONG && PA_20) {
809                         g(add_relocation(ctx, JMP_LONG, ctx->code_position - arg1, NULL));
810                         cgen_four(PARISC_BL_L | PARISC_N);
811                 } else {
812                         cgen_four(PARISC_BL | PARISC_N | assemble_12(3));
813                         g(add_relocation(ctx, JMP_EXTRA_LONG, ctx->code_position - arg1, NULL));
814                         cgen_four(PARISC_LDIL | ((uint32_t)R_CG_SCRATCH << 21));
815                         g(cgen_2reg(ctx, PARISC_LDO, R_CG_SCRATCH, R_CG_SCRATCH));
816                         g(cgen_2reg(ctx, PARISC_BLR | PARISC_N, R_ZERO, R_CG_SCRATCH));
817                         g(cgen_2reg(ctx, PARISC_BLR | PARISC_N, R_ZERO, R_CG_SCRATCH));
818                 }
819         }
821         return true;
823 invalid:
824         internal(file_line, "cgen_alu1: invalid arguments %02x, %02x, %u, %u", arg1[0], arg2[0], alu, writes_flags);
825         return false;
828 static bool attr_w cgen_sar(struct codegen_context *ctx, bool sar_complement, uint8_t reg)
830         uint32_t mc;
831         if (!sar_complement) {
832                 mc = PARISC_MTSAR;
833                 mc |= (uint32_t)reg << 16;
834                 cgen_four(mc);
835         } else if (PA_20) {
836                 mc = PARISC_MTSARCM;
837                 mc |= (uint32_t)reg << 16;
838                 cgen_four(mc);
839         } else {
840                 mc = PARISC_LDO;
841                 mc |= low_sign_ext_14(-1);
842                 g(cgen_2reg(ctx, mc, 0, R_CG_SCRATCH));
843                 mc = PARISC_XOR;
844                 g(cgen_3reg(ctx, mc, R_CG_SCRATCH, reg, R_CG_SCRATCH));
845                 mc = PARISC_MTSAR;
846                 mc |= (uint32_t)R_CG_SCRATCH << 16;
847                 cgen_four(mc);
848         }
849         return true;
852 static bool attr_w cgen_rot(struct codegen_context *ctx, unsigned size, unsigned rot)
854         uint32_t mc;
855         uint8_t *arg1 = ctx->code_position;
856         uint8_t *arg2 = arg1 + arg_size(*arg1);
857         uint8_t *arg3 = arg2 + arg_size(*arg2);
858         ctx->code_position = arg3 + arg_size(*arg3);
859         if (arg3[0] == ARG_IMM) {
860                 int64_t imm = get_imm(&arg3[1]);
861                 unsigned sh = imm & (size == OP_SIZE_4 ? 31 : 63);
862                 if (size == OP_SIZE_4) {
863                         switch (rot) {
864                                 case ROT_SHL:
865                                         mc = PARISC_DEPW_Z;
866                                         mc |= sh | (sh << 5);
867                                         break;
868                                 case ROT_SHR:
869                                         mc = PARISC_EXTRW_U;
870                                         mc |= sh | ((31 - sh) << 5);
871                                         break;
872                                 case ROT_SAR:
873                                         mc = PARISC_EXTRW_S;
874                                         mc |= sh | ((31 - sh) << 5);
875                                         break;
876                                 default:
877                                         goto invalid;
878                         }
879                 } else {
880                         switch (rot) {
881                                 case ROT_SHL:
882                                         mc = PARISC_DEPD_Z;
883                                         mc |= (sh & 31) | ((sh & 31) << 5);
884                                         if (sh & 32)
885                                                 mc ^= 0x1800;
886                                         break;
887                                 case ROT_SHR:
888                                         mc = PARISC_EXTRD_U;
889                                         mc |= (sh & 31) | ((31 - (sh & 31)) << 5);
890                                         if (sh & 32)
891                                                 mc ^= 0x1800;
892                                         break;
893                                 case ROT_SAR:
894                                         mc = PARISC_EXTRD_S;
895                                         mc |= (sh & 31) | ((31 - (sh & 31)) << 5);
896                                         if (sh & 32)
897                                                 mc ^= 0x1800;
898                                         break;
899                                 default:
900                                         goto invalid;
901                         }
902                 }
903                 if (rot == ROT_SHL)
904                         g(cgen_2reg(ctx, mc, arg1[0], arg2[0]));
905                 else
906                         g(cgen_2reg(ctx, mc, arg2[0], arg1[0]));
907                 return true;
908         } else if (arg3[0] < 0x20) {
909                 bool sar_complement = rot != ROT_SHR;
910                 g(cgen_sar(ctx, sar_complement, arg3[0]));
911                 if (size == OP_SIZE_4) {
912                         switch (rot) {
913                                 case ROT_SHL:
914                                         mc = PARISC_DEPW_Z_SAR;
915                                         break;
916                                 case ROT_SHR:
917                                         mc = PARISC_SHRPW_SAR;
918                                         break;
919                                 case ROT_SAR:
920                                         mc = PARISC_EXTRW_S_SAR;
921                                         break;
922                                 default:
923                                         goto invalid;
924                         }
925                 } else {
926                         switch (rot) {
927                                 case ROT_SHL:
928                                         mc = PARISC_DEPD_Z_SAR | 0x100;
929                                         break;
930                                 case ROT_SHR:
931                                         mc = PARISC_SHRPD_SAR;
932                                         break;
933                                 case ROT_SAR:
934                                         mc = PARISC_EXTRD_S_SAR | 0x100;
935                                         break;
936                                 default:
937                                         goto invalid;
938                         }
939                 }
940                 if (rot == ROT_SHL) {
941                         g(cgen_2reg(ctx, mc, arg1[0], arg2[0]));
942                 } else if (rot == ROT_SHR) {
943                         g(cgen_3reg(ctx, mc, R_ZERO, arg2[0], arg1[0]));
944                 } else {
945                         g(cgen_2reg(ctx, mc, arg2[0], arg1[0]));
946                 }
947                 return true;
948         }
950 invalid:
951         internal(file_line, "cgen_rot: invalid arguments %02x, %02x, %02x, %u, %u", arg1[0], arg2[0], arg3[0], size, rot);
952         return false;
955 static bool attr_w cgen_btx(struct codegen_context *ctx, unsigned size, unsigned aux)
957         uint32_t mc;
958         uint8_t *arg1 = ctx->code_position;
959         uint8_t *arg2 = arg1 + arg_size(*arg1);
960         uint8_t *arg3 = arg2 + arg_size(*arg2);
961         ctx->code_position = arg3 + arg_size(*arg3);
963         if (aux == BTX_BTS || aux == BTX_BTR) {
964                 if (arg1[0] != arg2[0]) {
965                         g(cgen_3reg(ctx, PARISC_OR, arg2[0], 0, arg1[0]));
966                 }
967         }
969         if (arg3[0] == ARG_IMM) {
970                 int64_t imm = get_imm(&arg3[1]);
971                 unsigned bit = imm & (size == OP_SIZE_4 ? 31 : 63);
972                 if (size == OP_SIZE_4) {
973                         switch (aux) {
974                                 case BTX_BTS:
975                                 case BTX_BTR:
976                                         mc = PARISC_DEPWI;
977                                         mc |= 31U | (bit << 5);
978                                         g(cgen_2reg(ctx, mc, arg1[0], low_sign_ext_5(aux == BTX_BTS)));
979                                         return true;
980                                 case BTX_BTEXT:
981                                         mc = PARISC_EXTRW_U;
982                                         mc |= 31U | ((31 - bit) << 5);
983                                         g(cgen_2reg(ctx, mc, arg2[0], arg1[0]));
984                                         return true;
985                                 default:
986                                         goto invalid;
987                         }
988                 } else {
989                         switch (aux) {
990                                 case BTX_BTS:
991                                 case BTX_BTR:
992                                         mc = PARISC_DEPDI;
993                                         mc |= 31U | ((bit & 0x1f) << 5) | ((bit & 0x20) << 6);
994                                         g(cgen_2reg(ctx, mc, arg1[0], low_sign_ext_5(aux == BTX_BTS)));
995                                         return true;
996                                 case BTX_BTEXT:
997                                         mc = PARISC_EXTRD_U;
998                                         mc |= 31U | (((63 - bit) & 0x1f) << 5) | (((63 - bit) & 0x20) << 6);
999                                         g(cgen_2reg(ctx, mc, arg2[0], arg1[0]));
1000                                         return true;
1001                                 default:
1002                                         goto invalid;
1003                         }
1004                 }
1005         } else {
1006                 g(cgen_sar(ctx, true, arg3[0]));
1007                 if (size == OP_SIZE_4) {
1008                         switch (aux) {
1009                                 case BTX_BTS:
1010                                 case BTX_BTR:
1011                                         mc = PARISC_DEPWI_SAR;
1012                                         mc |= 31U;
1013                                         g(cgen_2reg(ctx, mc, arg1[0], low_sign_ext_5(aux == BTX_BTS)));
1014                                         return true;
1015                                 case BTX_BTEXT:
1016                                         mc = PARISC_EXTRW_U_SAR;
1017                                         mc |= 31U;
1018                                         g(cgen_2reg(ctx, mc, arg2[0], arg1[0]));
1019                                         return true;
1020                                 default:
1021                                         goto invalid;
1022                         }
1023                 } else {
1024                         switch (aux) {
1025                                 case BTX_BTS:
1026                                 case BTX_BTR:
1027                                         mc = PARISC_DEPDI_SAR;
1028                                         mc |= 31U;
1029                                         g(cgen_2reg(ctx, mc, arg1[0], low_sign_ext_5(aux == BTX_BTS)));
1030                                         return true;
1031                                 case BTX_BTEXT:
1032                                         mc = PARISC_EXTRD_U_SAR;
1033                                         mc |= 31U;
1034                                         g(cgen_2reg(ctx, mc, arg2[0], arg1[0]));
1035                                         return true;
1036                                 default:
1037                                         goto invalid;
1038                         }
1039                 }
1040         }
1042 invalid:
1043         internal(file_line, "cgen_btx: invalid arguments %02x, %02x, %02x, %u, %u", arg1[0], arg2[0], arg3[0], size, aux);
1044         return false;
1047 static bool attr_w cgen_movr(struct codegen_context *ctx, unsigned cond)
1049         int32_t fc;
1050         uint32_t mc;
1051         uint8_t *arg1 = ctx->code_position;
1052         uint8_t *arg2 = arg1 + arg_size(*arg1);
1053         uint8_t *arg3 = arg2 + arg_size(*arg2);
1054         uint8_t *arg4 = arg3 + arg_size(*arg3);
1055         ctx->code_position = arg4 + arg_size(*arg4);
1057         fc = cmp_sub_cond[cond];
1058         fc ^= PARISC_COND_NEG;
1060         if (unlikely(arg1[0] != arg2[0]) || unlikely(arg1[0] >= 0x20))
1061                 internal(file_line, "cgen_movr: invalid arguments");
1063         mc = PARISC_ADD_L;
1064         mc |= fc;
1065         if (OP_SIZE_NATIVE == OP_SIZE_8)
1066                 mc |= PARISC_COND_64;
1068         g(cgen_3reg(ctx, mc, R_ZERO, arg3[0], R_ZERO));
1070         g(cgen_mov_args(ctx, OP_SIZE_NATIVE, arg1, arg4));
1072         return true;
1075 static bool attr_w cgen_fp_cmp_cond(struct codegen_context *ctx, unsigned op_size, unsigned aux)
1077         uint32_t mc;
1078         unsigned cond;
1079         uint8_t *arg1 = ctx->code_position;
1080         uint8_t *arg2 = arg1 + arg_size(*arg1);
1081         ctx->code_position = arg2 + arg_size(*arg2);
1082         switch (aux) {
1083                 case FP_COND_P:         cond = PARISC_FCMP_P; break;
1084                 case FP_COND_NP:        cond = PARISC_FCMP_NP; break;
1085                 case FP_COND_E:         cond = PARISC_FCMP_E; break;
1086                 case FP_COND_NE:        cond = PARISC_FCMP_NE; break;
1087                 case FP_COND_A:         cond = PARISC_FCMP_A; break;
1088                 case FP_COND_BE:        cond = PARISC_FCMP_BE; break;
1089                 case FP_COND_B:         cond = PARISC_FCMP_B; break;
1090                 case FP_COND_AE:        cond = PARISC_FCMP_AE; break;
1091                 default:                internal(file_line, "cgen_fp_cmp_cond: invalid condition %u", aux);
1092                                         return false;
1093         }
1094         mc = PARISC_FCMP;
1095         if (op_size == OP_SIZE_8)
1096                 mc |= PARISC_FP_DOUBLE;
1097         g(cgen_3reg(ctx, mc, arg1[0] & 0x1f, arg2[0] & 0x1f, cond));
1098         return true;
1101 static bool attr_w cgen_fp_test_reg(struct codegen_context *ctx)
1103         unsigned reg = cget_one(ctx);
1104         uint32_t mc;
1106         mc = PARISC_LDO;
1107         mc |= low_sign_ext_14(1);
1108         g(cgen_2reg(ctx, mc, R_ZERO, reg));
1110         cgen_four(PARISC_FTEST);
1112         mc = PARISC_LDO;
1113         mc |= low_sign_ext_14(0);
1114         g(cgen_2reg(ctx, mc, R_ZERO, reg));
1116         return true;
1119 static bool attr_w cgen_fp_alu(struct codegen_context *ctx, unsigned op_size, unsigned aux)
1121         uint32_t mc;
1122         uint8_t *arg1 = ctx->code_position;
1123         uint8_t *arg2 = arg1 + arg_size(*arg1);
1124         uint8_t *arg3 = arg2 + arg_size(*arg2);
1125         ctx->code_position = arg3 + arg_size(*arg3);
1126         switch (aux) {
1127                 case FP_ALU_ADD:        mc = PARISC_FADD; break;
1128                 case FP_ALU_SUB:        mc = PARISC_FSUB; break;
1129                 case FP_ALU_MUL:        mc = PARISC_FMPY; break;
1130                 case FP_ALU_DIV:        mc = PARISC_FDIV; break;
1131                 default:                internal(file_line, "cgen_fp_alu: invalid alu %u", aux);
1132         }
1133         switch (op_size) {
1134                 case OP_SIZE_4:         break;
1135                 case OP_SIZE_8:         mc |= PARISC_FP_DOUBLE; break;
1136                 default:                internal(file_line, "cgen_fp_alu: invalid size %u", op_size);
1137         }
1138         g(cgen_3reg(ctx, mc, arg3[0] & 0x1f, arg2[0] & 0x1f, arg1[0] & 0x1f));
1139         return true;
1142 static bool attr_w cgen_fp_alu1(struct codegen_context *ctx, unsigned op_size, unsigned aux)
1144         uint32_t mc;
1145         uint8_t *arg1 = ctx->code_position;
1146         uint8_t *arg2 = arg1 + arg_size(*arg1);
1147         ctx->code_position = arg2 + arg_size(*arg2);
1148         switch (aux) {
1149                 case FP_ALU1_NEG:       mc = PARISC_FNEG; break;
1150                 case FP_ALU1_SQRT:      mc = PARISC_FSQRT; break;
1151                 default:                internal(file_line, "cgen_fp_alu1: invalid alu %u", aux);
1152         }
1153         switch (op_size) {
1154                 case OP_SIZE_4:         break;
1155                 case OP_SIZE_8:         mc |= PARISC_FP_DOUBLE; break;
1156                 default:                internal(file_line, "cgen_fp_alu: invalid size %u", op_size);
1157         }
1158         g(cgen_3reg(ctx, mc, 0, arg2[0] & 0x1f, arg1[0] & 0x1f));
1159         return true;
1162 static bool attr_w cgen_fp_to_int(struct codegen_context *ctx, unsigned int_op_size, unsigned fp_op_size)
1164         uint32_t mc;
1165         uint8_t *arg1 = ctx->code_position;
1166         uint8_t *arg2 = arg1 + arg_size(*arg1);
1167         ctx->code_position = arg2 + arg_size(*arg2);
1169         mc = PARISC_FCNVFXT;
1170         if (int_op_size == OP_SIZE_8)
1171                 mc |= PARISC_FCNVFXT_TO_LONG;
1172         if (fp_op_size == OP_SIZE_8)
1173                 mc |= PARISC_FCNVFXT_FROM_DOUBLE;
1174         mc |= arg1[0] & 0x1f;
1175         mc |= (uint32_t)(arg2[0] & 0x1f) << 21;
1176         cgen_four(mc);
1177         return true;
1180 static bool attr_w cgen_fp_from_int(struct codegen_context *ctx, unsigned int_op_size, unsigned fp_op_size)
1182         uint32_t mc;
1183         uint8_t *arg1 = ctx->code_position;
1184         uint8_t *arg2 = arg1 + arg_size(*arg1);
1185         ctx->code_position = arg2 + arg_size(*arg2);
1187         mc = PARISC_FCNVXF;
1188         if (int_op_size == OP_SIZE_8)
1189                 mc |= PARISC_FCNVXF_FROM_LONG;
1190         if (fp_op_size == OP_SIZE_8)
1191                 mc |= PARISC_FCNVXF_TO_DOUBLE;
1192         mc |= arg1[0] & 0x1f;
1193         mc |= (uint32_t)(arg2[0] & 0x1f) << 21;
1194         cgen_four(mc);
1195         return true;
1198 static bool attr_w cgen_cond_jmp(struct codegen_context *ctx, uint32_t mc, unsigned length, unsigned reg1, unsigned reg2, int reloc_offset)
1200         if (length == JMP_SHORTEST) {
1201                 bool need_nop;
1202                 mc |= PARISC_N;
1203                 g(add_relocation(ctx, JMP_SHORTEST, reloc_offset, &need_nop));
1204                 g(cgen_2reg(ctx, mc, reg2, reg1));
1205                 if (unlikely(need_nop))
1206                         cgen_four(PARISC_NOP);
1207         } else if (length == JMP_SHORT) {
1208                 mc |= PARISC_N;
1209                 g(cgen_2reg(ctx, mc, reg2, reg1));
1210                 g(add_relocation(ctx, JMP_SHORT, reloc_offset, NULL));
1211                 cgen_four(PARISC_BL | PARISC_N);
1212         } else if (length == JMP_LONG && PA_20) {
1213                 mc |= PARISC_N;
1214                 g(cgen_2reg(ctx, mc, reg2, reg1));
1215                 g(add_relocation(ctx, JMP_LONG, reloc_offset, NULL));
1216                 cgen_four(PARISC_BL_L | PARISC_N);
1217         } else {
1218                 mc |= PARISC_N;
1219                 mc |= assemble_12(3);
1220                 g(cgen_2reg(ctx, mc, reg2, reg1));
1221                 g(add_relocation(ctx, JMP_EXTRA_LONG, reloc_offset, NULL));
1222                 cgen_four(PARISC_LDIL | ((uint32_t)R_CG_SCRATCH << 21));
1223                 g(cgen_2reg(ctx, PARISC_LDO, R_CG_SCRATCH, R_CG_SCRATCH));
1224                 g(cgen_2reg(ctx, PARISC_BLR | PARISC_N, R_ZERO, R_CG_SCRATCH));
1225                 g(cgen_2reg(ctx, PARISC_BLR | PARISC_N, R_ZERO, R_CG_SCRATCH));
1226         }
1227         return true;
1230 static bool attr_w cgen_jmp_12regs(struct codegen_context *ctx, unsigned size, unsigned cond, unsigned length, unsigned reg1, unsigned reg2, int reloc_offset)
1232         int32_t fc;
1233         uint32_t mc;
1234         fc = cmp_sub_cond[cond];
1235         if (length > JMP_SHORTEST)
1236                 fc ^= PARISC_COND_NEG;
1237         if (size == OP_SIZE_4)
1238                 mc = !(fc & PARISC_COND_NEG) ? PARISC_CMPB : PARISC_CMPB_NOT;
1239         else
1240                 mc = !(fc & PARISC_COND_NEG) ? PARISC_CMPB_64 : PARISC_CMPB_64_NOT;
1241         mc |= ((uint32_t)fc & ~PARISC_COND_NEG);
1242         g(cgen_cond_jmp(ctx, mc, length, reg1, reg2, reloc_offset));
1243         return true;
1246 static bool attr_w cgen_jmp(struct codegen_context *ctx, unsigned length)
1248         if (length <= JMP_SHORT) {
1249                 g(add_relocation(ctx, JMP_SHORT, 0, NULL));
1250                 cgen_four(PARISC_BL | PARISC_N);
1251         } else if (length == JMP_LONG && PA_20) {
1252                 g(add_relocation(ctx, JMP_LONG, 0, NULL));
1253                 cgen_four(PARISC_BL_L | PARISC_N);
1254         } else {
1255                 g(add_relocation(ctx, JMP_EXTRA_LONG, 0, NULL));
1256                 cgen_four(PARISC_LDIL | ((uint32_t)R_CG_SCRATCH << 21));
1257                 g(cgen_2reg(ctx, PARISC_LDO, R_CG_SCRATCH, R_CG_SCRATCH));
1258                 g(cgen_2reg(ctx, PARISC_BLR | PARISC_N, R_ZERO, R_CG_SCRATCH));
1259                 g(cgen_2reg(ctx, PARISC_BLR | PARISC_N, R_ZERO, R_CG_SCRATCH));
1260         }
1261         return true;
1264 static bool attr_w cgen_jmp_reg(struct codegen_context *ctx, unsigned size, unsigned cond, unsigned length)
1266         unsigned reg = cget_one(ctx);
1267         return cgen_jmp_12regs(ctx, size, cond, length, reg, 0, 1);
1270 static bool attr_w cgen_jmp_reg_bit(struct codegen_context *ctx, unsigned size, unsigned bit, bool jnz, unsigned length)
1272         uint32_t mc;
1273         unsigned reg = cget_one(ctx);
1274         if (length > JMP_SHORTEST)
1275                 jnz = !jnz;
1276         if (size == OP_SIZE_4 || bit < 32) {
1277                 bit = 31 - bit;
1278                 mc = jnz ? PARISC_BB_1 : PARISC_BB_0;
1279         } else {
1280                 bit = 63 - bit;
1281                 mc = jnz ? PARISC_BB_64_1 : PARISC_BB_64_0;
1282         }
1283         g(cgen_cond_jmp(ctx, mc, length, reg, bit, 1));
1284         return true;
1287 static bool attr_w cgen_jmp_2regs(struct codegen_context *ctx, unsigned size, unsigned cond, unsigned length)
1289         uint8_t *arg1 = ctx->code_position;
1290         uint8_t *arg2 = arg1 + arg_size(*arg1);
1291         ctx->code_position = arg2 + arg_size(*arg2);
1292         if (arg2[0] < 0x20)
1293                 return cgen_jmp_12regs(ctx, size, cond, length, arg1[0], arg2[0], 2);
1294         if (arg2[0] == ARG_IMM) {
1295                 int64_t imm = get_imm(&arg2[1]);
1296                 uint32_t mc;
1297                 int32_t fc;
1298                 cond = cmp_swap_arguments(cond);
1299                 fc = cmp_sub_cond[cond];
1300                 if (length > JMP_SHORTEST)
1301                         fc ^= PARISC_COND_NEG;
1302                 if (size == OP_SIZE_4) {
1303                         mc = fc & PARISC_COND_NEG ? PARISC_CMPIB_NOT : PARISC_CMPIB;
1304                         mc |= fc & ~PARISC_COND_NEG;
1305                 } else {
1306                         mc = PARISC_CMPIB_64;
1307                         switch (fc) {
1308                                 case PARISC_COND_EQUAL:         mc |= 1 << 13; break;
1309                                 case PARISC_COND_NOT_EQUAL:     mc |= 5 << 13; break;
1310                                 case PARISC_COND_L_S:           mc |= 2 << 13; break;
1311                                 case PARISC_COND_GE_S:          mc |= 6 << 13; break;
1312                                 case PARISC_COND_LE_S:          mc |= 3 << 13; break;
1313                                 case PARISC_COND_G_S:           mc |= 7 << 13; break;
1314                                 case PARISC_COND_L_U:           mc |= 0 << 13; break;
1315                                 case PARISC_COND_GE_U:          mc |= 4 << 13; break;
1316                                 default:        internal(file_line, "cgen_jmp_2regs: unsupported condition %x", fc);
1317                         }
1318                 }
1319                 g(cgen_cond_jmp(ctx, mc, length, low_sign_ext_5(imm), arg1[0], 10));
1320                 return true;
1321         }
1322         internal(file_line, "cgen_jmp_2regs: invalid arguments %02x, %02x", arg1[0], arg2[0]);
1323         return false;
1326 static bool attr_w cgen_jmp_fp_test(struct codegen_context *ctx, unsigned length)
1328         cgen_four(PARISC_FTEST);
1329         if (length <= JMP_SHORT) {
1330                 g(add_relocation(ctx, JMP_SHORT, 0, NULL));
1331                 cgen_four(PARISC_BL | PARISC_N);
1332         } else if (length == JMP_LONG && PA_20) {
1333                 g(add_relocation(ctx, JMP_LONG, 0, NULL));
1334                 cgen_four(PARISC_BL_L | PARISC_N);
1335         } else {
1336                 cgen_four(PARISC_BL | PARISC_N | assemble_12(0));
1337                 cgen_four(PARISC_BL | PARISC_N | assemble_12(3));
1338                 g(add_relocation(ctx, JMP_EXTRA_LONG, 0, NULL));
1339                 cgen_four(PARISC_LDIL | ((uint32_t)R_CG_SCRATCH << 21));
1340                 g(cgen_2reg(ctx, PARISC_LDO, R_CG_SCRATCH, R_CG_SCRATCH));
1341                 g(cgen_2reg(ctx, PARISC_BLR | PARISC_N, R_ZERO, R_CG_SCRATCH));
1342                 g(cgen_2reg(ctx, PARISC_BLR | PARISC_N, R_ZERO, R_CG_SCRATCH));
1343         }
1344         return true;
1347 static bool attr_w cgen_jmp_indirect(struct codegen_context *ctx, unsigned reg)
1349         uint32_t mc;
1350 #ifdef ARCH_PARISC32
1351 #ifdef ARCH_PARISC_USE_STUBS
1352 #endif
1353         if (PA_20) {
1354                 mc = PARISC_BVE_RET;
1355                 mc |= (uint32_t)reg << 21;
1356                 mc |= PARISC_N;
1357                 cgen_four(mc);
1358         } else {
1359                 if (PA_SPACES) {
1360                         mc = PARISC_LDSID;
1361                         mc |= (uint32_t)reg << 21;
1362                         mc |= R_CG_SCRATCH;
1363                         cgen_four(mc);
1364                         mc = PARISC_MTSP;
1365                         mc |= (uint32_t)R_CG_SCRATCH << 16;
1366                         cgen_four(mc);
1367                         mc = PARISC_BE;
1368                         mc |= (uint32_t)reg << 21;
1369                         mc |= PARISC_N;
1370                         cgen_four(mc);
1371                 } else {
1372                         mc = PARISC_BV;
1373                         mc |= (uint32_t)reg << 21;
1374                         mc |= PARISC_N;
1375                         cgen_four(mc);
1376                 }
1377         }
1378 #else
1379         mc = PARISC_BV;
1380         mc |= (uint32_t)reg << 21;
1381         mc |= PARISC_N;
1382         cgen_four(mc);
1383 #endif
1384         if (unlikely(!ctx->fn))
1385                 cgen_four(PARISC_NOP);
1386         return true;
1389 static bool attr_w cgen_call_millicode(struct codegen_context attr_unused *ctx)
1391 #ifdef ARCH_PARISC32
1392         uint32_t mc;
1393         unsigned reg = R_SCRATCH_NA_1;
1394         unsigned bit;
1396         mc = PARISC_BB_0;
1397         bit = 31 - 1;
1398         mc |= assemble_12(1);
1399         mc |= PARISC_N;
1400         g(cgen_2reg(ctx, mc, bit, reg));
1402         mc = PARISC_LD_ST;
1403         mc |= PARISC_LD_ST_W;
1404         mc |= PARISC_LD_ST_IMM;
1405         mc |= PARISC_LD_ST_LD;
1406         g(cgen_3reg(ctx, mc, low_sign_ext_5(2), reg, R_19));
1407         g(cgen_3reg(ctx, mc, low_sign_ext_5(-2), reg, reg));
1409         g(cgen_jmp_indirect(ctx, reg));
1410 #endif
1411         return true;
1414 static bool attr_w resolve_relocation(struct codegen_context *ctx, struct relocation *reloc)
1416         uint32_t mc;
1417         uint32_t mc4[4];
1418         int64_t offs = (int64_t)(ctx->label_to_pos[reloc->label_id] >> 2) - (int64_t)(reloc->position >> 2) - 2;
1419         switch (reloc->length) {
1420                 case JMP_SHORTEST:
1421                         if (unlikely(offs < -0x800) || unlikely(offs >= 0x800))
1422                                 return false;
1423                         memcpy(&mc, ctx->mcode + reloc->position, 4);
1424                         mc &= ~0x00001ffdU;
1425                         mc |= assemble_12(offs);
1426                         memcpy(ctx->mcode + reloc->position, &mc, 4);
1427                         return true;
1428                 case JMP_SHORT:
1429                         if (unlikely(offs < -0x10000) || unlikely(offs >= 0x10000))
1430                                 return false;
1431                         memcpy(&mc, ctx->mcode + reloc->position, 4);
1432                         mc &= ~0x001f1ffdU;
1433                         mc |= assemble_17(offs);
1434                         memcpy(ctx->mcode + reloc->position, &mc, 4);
1435                         return true;
1436                 case JMP_LONG:
1437                         if (unlikely(offs < -0x200000) || unlikely(offs >= 0x200000))
1438                                 return false;
1439                         memcpy(&mc, ctx->mcode + reloc->position, 4);
1440                         mc &= ~0x03ff1ffdU;
1441                         mc |= assemble_22(offs);
1442                         memcpy(ctx->mcode + reloc->position, &mc, 4);
1443                         return true;
1444                 case JMP_EXTRA_LONG:
1445                         offs -= 2;
1446                         if (unlikely(offs != (int32_t)offs))
1447                                 return false;
1448                         memcpy(&mc4, ctx->mcode + reloc->position, 16);
1449                         mc4[0] &= ~0x001fffffU;
1450                         mc4[0] |= assemble_21((uint64_t)offs >> 1 >> 11);
1451                         mc4[1] &= ~0x00003fffU;
1452                         mc4[1] |= low_sign_ext_14(((uint64_t)offs >> 1) & 0x7ff);
1453                         if (offs & 1)
1454                                 mc4[2] = PARISC_NOP;
1455                         else
1456                                 mc4[3] = PARISC_NOP;
1457                         memcpy(ctx->mcode + reloc->position, &mc4, 16);
1458                         return true;
1459                 default:
1460                         internal(file_line, "resolve_relocation: invalid relocation length %u", reloc->length);
1461         }
1462         return false;
1465 static bool attr_w cgen_insn(struct codegen_context *ctx, uint32_t insn)
1467         /*debug("insn: %08x", insn);*/
1468         switch (insn_opcode(insn)) {
1469                 case INSN_ENTRY:
1470                         g(cgen_entry(ctx));
1471                         return true;
1472                 case INSN_LABEL:
1473                         g(cgen_label(ctx));
1474                         return true;
1475                 case INSN_RET:
1476                         g(cgen_ret(ctx));
1477                         return true;
1478                 case INSN_CALL:
1479                         g(cgen_call(ctx, insn_jump_size(insn)));
1480                         return true;
1481                 case INSN_CALL_INDIRECT:
1482                         g(cgen_call_indirect(ctx));
1483                         return true;
1484                 case INSN_MOV:
1485                         g(cgen_mov(ctx, insn_op_size(insn)));
1486                         return true;
1487                 case INSN_MOVSX:
1488                         g(cgen_movsx(ctx, insn_op_size(insn)));
1489                         return true;
1490                 case INSN_CMP_DEST_REG:
1491                         if (unlikely(insn_op_size(insn) < OP_SIZE_4))
1492                                 goto invalid_insn;
1493                         g(cgen_cmp_dest_reg(ctx, insn_op_size(insn), insn_aux(insn)));
1494                         return true;
1495                 case INSN_ALU:
1496                 case INSN_ALU_FLAGS:
1497                         if (unlikely(insn_op_size(insn) < OP_SIZE_4))
1498                                 goto invalid_insn;
1499                         g(cgen_alu(ctx, insn_op_size(insn), insn_writes_flags(insn), insn_aux(insn), false, insn_jump_size(insn)));
1500                         return true;
1501                 case INSN_ALU_TRAP:
1502                 case INSN_ALU_FLAGS_TRAP:
1503                         if (unlikely(insn_op_size(insn) < OP_SIZE_4))
1504                                 goto invalid_insn;
1505                         g(cgen_alu(ctx, insn_op_size(insn), insn_writes_flags(insn), insn_aux(insn), true, insn_jump_size(insn)));
1506                         return true;
1507                 case INSN_ALU1:
1508                         if (unlikely(insn_op_size(insn) < OP_SIZE_4))
1509                                 goto invalid_insn;
1510                         g(cgen_alu1(ctx, insn_op_size(insn), insn_writes_flags(insn), insn_aux(insn), false, insn_jump_size(insn)));
1511                         return true;
1512                 case INSN_ALU1_TRAP:
1513                         if (unlikely(insn_op_size(insn) < OP_SIZE_4))
1514                                 goto invalid_insn;
1515                         g(cgen_alu1(ctx, insn_op_size(insn), insn_writes_flags(insn), insn_aux(insn), true, insn_jump_size(insn)));
1516                         return true;
1517                 case INSN_ROT:
1518                         if (unlikely(insn_op_size(insn) < OP_SIZE_4) || unlikely(insn_writes_flags(insn) != 0))
1519                                 goto invalid_insn;
1520                         g(cgen_rot(ctx, insn_op_size(insn), insn_aux(insn)));
1521                         return true;
1522                 case INSN_BTX:
1523                         if (unlikely(insn_op_size(insn) < OP_SIZE_4))
1524                                 goto invalid_insn;
1525                         g(cgen_btx(ctx, insn_op_size(insn), insn_aux(insn)));
1526                         return true;
1527                 case INSN_MOVR:
1528                         if (unlikely(insn_op_size(insn) != OP_SIZE_NATIVE) || unlikely(insn_writes_flags(insn) != 0))
1529                                 goto invalid_insn;
1530                         g(cgen_movr(ctx, insn_aux(insn)));
1531                         return true;
1532                 case INSN_FP_CMP_COND:
1533                         g(cgen_fp_cmp_cond(ctx, insn_op_size(insn), insn_aux(insn)));
1534                         return true;
1535                 case INSN_FP_TEST_REG:
1536                         g(cgen_fp_test_reg(ctx));
1537                         return true;
1538                 case INSN_FP_ALU:
1539                         g(cgen_fp_alu(ctx, insn_op_size(insn), insn_aux(insn)));
1540                         return true;
1541                 case INSN_FP_ALU1:
1542                         g(cgen_fp_alu1(ctx, insn_op_size(insn), insn_aux(insn)));
1543                         return true;
1544                 case INSN_FP_TO_INT32:
1545                 case INSN_FP_TO_INT64:
1546                         g(cgen_fp_to_int(ctx, insn_opcode(insn) == INSN_FP_TO_INT32 ? OP_SIZE_4 : OP_SIZE_8, insn_op_size(insn)));
1547                         return true;
1548                 case INSN_FP_FROM_INT32:
1549                 case INSN_FP_FROM_INT64:
1550                         g(cgen_fp_from_int(ctx, insn_opcode(insn) == INSN_FP_FROM_INT32 ? OP_SIZE_4 : OP_SIZE_8, insn_op_size(insn)));
1551                         return true;
1552                 case INSN_JMP:
1553                         g(cgen_jmp(ctx, insn_jump_size(insn)));
1554                         return true;
1555                 case INSN_JMP_REG:
1556                         if (unlikely(insn_op_size(insn) < OP_SIZE_4))
1557                                 goto invalid_insn;
1558                         g(cgen_jmp_reg(ctx, insn_op_size(insn), insn_aux(insn), insn_jump_size(insn)));
1559                         return true;
1560                 case INSN_JMP_REG_BIT:
1561                         if (unlikely(insn_op_size(insn) < OP_SIZE_4))
1562                                 goto invalid_insn;
1563                         g(cgen_jmp_reg_bit(ctx, insn_op_size(insn), insn_aux(insn) & 63, insn_aux(insn) >> 6, insn_jump_size(insn)));
1564                         return true;
1565                 case INSN_JMP_2REGS:
1566                         if (unlikely(insn_op_size(insn) < OP_SIZE_4))
1567                                 goto invalid_insn;
1568                         g(cgen_jmp_2regs(ctx, insn_op_size(insn), insn_aux(insn), insn_jump_size(insn)));
1569                         return true;
1570                 case INSN_JMP_FP_TEST:
1571                         g(cgen_jmp_fp_test(ctx, insn_jump_size(insn)));
1572                         return true;
1573                 case INSN_JMP_INDIRECT:
1574                         g(cgen_jmp_indirect(ctx, cget_one(ctx)));
1575                         return true;
1576                 case INSN_CALL_MILLICODE:
1577                         g(cgen_call_millicode(ctx));
1578                         return true;
1579                 default:
1580                 invalid_insn:
1581                         internal(file_line, "cgen_insn: invalid insn %08x", insn);
1582                         return false;
1583         }