1e3130936SPhilippe Mathieu-Daudé /*
2e3130936SPhilippe Mathieu-Daudé * MIPS translation routines.
3e3130936SPhilippe Mathieu-Daudé *
4e3130936SPhilippe Mathieu-Daudé * Copyright (c) 2004-2005 Jocelyn Mayer
5e3130936SPhilippe Mathieu-Daudé *
6e3130936SPhilippe Mathieu-Daudé * SPDX-License-Identifier: LGPL-2.1-or-later
7e3130936SPhilippe Mathieu-Daudé */
8e3130936SPhilippe Mathieu-Daudé #ifndef TARGET_MIPS_TRANSLATE_H
9e3130936SPhilippe Mathieu-Daudé #define TARGET_MIPS_TRANSLATE_H
10e3130936SPhilippe Mathieu-Daudé
118cab4157SRichard Henderson #include "cpu.h"
12f15f8935SRichard Henderson #include "tcg/tcg-op.h"
138cab4157SRichard Henderson #include "exec/translator.h"
148cab4157SRichard Henderson #include "exec/helper-gen.h"
158cab4157SRichard Henderson #include "qemu/log.h"
16e3130936SPhilippe Mathieu-Daudé
1746c9e2b3SPhilippe Mathieu-Daudé #define MIPS_DEBUG_DISAS 0
1846c9e2b3SPhilippe Mathieu-Daudé
19e3130936SPhilippe Mathieu-Daudé typedef struct DisasContext {
20e3130936SPhilippe Mathieu-Daudé DisasContextBase base;
21e3130936SPhilippe Mathieu-Daudé target_ulong saved_pc;
22e3130936SPhilippe Mathieu-Daudé target_ulong page_start;
23e3130936SPhilippe Mathieu-Daudé uint32_t opcode;
24e3130936SPhilippe Mathieu-Daudé uint64_t insn_flags;
250cfd392dSPhilippe Mathieu-Daudé int32_t CP0_Config0;
26e3130936SPhilippe Mathieu-Daudé int32_t CP0_Config1;
27e3130936SPhilippe Mathieu-Daudé int32_t CP0_Config2;
28e3130936SPhilippe Mathieu-Daudé int32_t CP0_Config3;
29e3130936SPhilippe Mathieu-Daudé int32_t CP0_Config5;
30e3130936SPhilippe Mathieu-Daudé /* Routine used to access memory */
31e3130936SPhilippe Mathieu-Daudé int mem_idx;
32e3130936SPhilippe Mathieu-Daudé MemOp default_tcg_memop_mask;
33e3130936SPhilippe Mathieu-Daudé uint32_t hflags, saved_hflags;
34e3130936SPhilippe Mathieu-Daudé target_ulong btarget;
35e3130936SPhilippe Mathieu-Daudé bool ulri;
36e3130936SPhilippe Mathieu-Daudé int kscrexist;
37e3130936SPhilippe Mathieu-Daudé bool rxi;
38e3130936SPhilippe Mathieu-Daudé int ie;
39e3130936SPhilippe Mathieu-Daudé bool bi;
40e3130936SPhilippe Mathieu-Daudé bool bp;
41e3130936SPhilippe Mathieu-Daudé uint64_t PAMask;
42e3130936SPhilippe Mathieu-Daudé bool mvh;
43e3130936SPhilippe Mathieu-Daudé bool eva;
44e3130936SPhilippe Mathieu-Daudé bool sc;
45e3130936SPhilippe Mathieu-Daudé int CP0_LLAddr_shift;
46e3130936SPhilippe Mathieu-Daudé bool ps;
47e3130936SPhilippe Mathieu-Daudé bool vp;
48e3130936SPhilippe Mathieu-Daudé bool cmgcr;
49e3130936SPhilippe Mathieu-Daudé bool mrp;
50e3130936SPhilippe Mathieu-Daudé bool nan2008;
51e3130936SPhilippe Mathieu-Daudé bool abs2008;
52e3130936SPhilippe Mathieu-Daudé bool mi;
53e3130936SPhilippe Mathieu-Daudé int gi;
54e3130936SPhilippe Mathieu-Daudé } DisasContext;
55e3130936SPhilippe Mathieu-Daudé
56d44971e7SRichard Henderson #define DISAS_STOP DISAS_TARGET_0
57d44971e7SRichard Henderson #define DISAS_EXIT DISAS_TARGET_1
58d44971e7SRichard Henderson #define DISAS_SEMIHOST DISAS_TARGET_2
59d44971e7SRichard Henderson
6046c9e2b3SPhilippe Mathieu-Daudé /* MIPS major opcodes */
6146c9e2b3SPhilippe Mathieu-Daudé #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
6246c9e2b3SPhilippe Mathieu-Daudé
6357eedcf7SPhilippe Mathieu-Daudé #define OPC_CP1 (0x11 << 26)
6457eedcf7SPhilippe Mathieu-Daudé
6557eedcf7SPhilippe Mathieu-Daudé /* Coprocessor 1 (rs field) */
6657eedcf7SPhilippe Mathieu-Daudé #define MASK_CP1(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
6757eedcf7SPhilippe Mathieu-Daudé
6857eedcf7SPhilippe Mathieu-Daudé /* Values for the fmt field in FP instructions */
6957eedcf7SPhilippe Mathieu-Daudé enum {
7057eedcf7SPhilippe Mathieu-Daudé /* 0 - 15 are reserved */
7157eedcf7SPhilippe Mathieu-Daudé FMT_S = 16, /* single fp */
7257eedcf7SPhilippe Mathieu-Daudé FMT_D = 17, /* double fp */
7357eedcf7SPhilippe Mathieu-Daudé FMT_E = 18, /* extended fp */
7457eedcf7SPhilippe Mathieu-Daudé FMT_Q = 19, /* quad fp */
7557eedcf7SPhilippe Mathieu-Daudé FMT_W = 20, /* 32-bit fixed */
7657eedcf7SPhilippe Mathieu-Daudé FMT_L = 21, /* 64-bit fixed */
7757eedcf7SPhilippe Mathieu-Daudé FMT_PS = 22, /* paired single fp */
7857eedcf7SPhilippe Mathieu-Daudé /* 23 - 31 are reserved */
7957eedcf7SPhilippe Mathieu-Daudé };
8057eedcf7SPhilippe Mathieu-Daudé
8157eedcf7SPhilippe Mathieu-Daudé enum {
8257eedcf7SPhilippe Mathieu-Daudé OPC_MFC1 = (0x00 << 21) | OPC_CP1,
8357eedcf7SPhilippe Mathieu-Daudé OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
8457eedcf7SPhilippe Mathieu-Daudé OPC_CFC1 = (0x02 << 21) | OPC_CP1,
8557eedcf7SPhilippe Mathieu-Daudé OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
8657eedcf7SPhilippe Mathieu-Daudé OPC_MTC1 = (0x04 << 21) | OPC_CP1,
8757eedcf7SPhilippe Mathieu-Daudé OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
8857eedcf7SPhilippe Mathieu-Daudé OPC_CTC1 = (0x06 << 21) | OPC_CP1,
8957eedcf7SPhilippe Mathieu-Daudé OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
9057eedcf7SPhilippe Mathieu-Daudé OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
9157eedcf7SPhilippe Mathieu-Daudé OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
9257eedcf7SPhilippe Mathieu-Daudé OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
9357eedcf7SPhilippe Mathieu-Daudé OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
9457eedcf7SPhilippe Mathieu-Daudé OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
9557eedcf7SPhilippe Mathieu-Daudé OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
9657eedcf7SPhilippe Mathieu-Daudé OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
9757eedcf7SPhilippe Mathieu-Daudé OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
9857eedcf7SPhilippe Mathieu-Daudé OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
9957eedcf7SPhilippe Mathieu-Daudé OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
10057eedcf7SPhilippe Mathieu-Daudé OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
10157eedcf7SPhilippe Mathieu-Daudé OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
10257eedcf7SPhilippe Mathieu-Daudé };
10357eedcf7SPhilippe Mathieu-Daudé
10457eedcf7SPhilippe Mathieu-Daudé #define MASK_CP1_FUNC(op) (MASK_CP1(op) | (op & 0x3F))
10557eedcf7SPhilippe Mathieu-Daudé #define MASK_BC1(op) (MASK_CP1(op) | (op & (0x3 << 16)))
10657eedcf7SPhilippe Mathieu-Daudé
10757eedcf7SPhilippe Mathieu-Daudé enum {
10857eedcf7SPhilippe Mathieu-Daudé OPC_BC1F = (0x00 << 16) | OPC_BC1,
10957eedcf7SPhilippe Mathieu-Daudé OPC_BC1T = (0x01 << 16) | OPC_BC1,
11057eedcf7SPhilippe Mathieu-Daudé OPC_BC1FL = (0x02 << 16) | OPC_BC1,
11157eedcf7SPhilippe Mathieu-Daudé OPC_BC1TL = (0x03 << 16) | OPC_BC1,
11257eedcf7SPhilippe Mathieu-Daudé };
11357eedcf7SPhilippe Mathieu-Daudé
11457eedcf7SPhilippe Mathieu-Daudé enum {
11557eedcf7SPhilippe Mathieu-Daudé OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
11657eedcf7SPhilippe Mathieu-Daudé OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
11757eedcf7SPhilippe Mathieu-Daudé };
11857eedcf7SPhilippe Mathieu-Daudé
11957eedcf7SPhilippe Mathieu-Daudé enum {
12057eedcf7SPhilippe Mathieu-Daudé OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
12157eedcf7SPhilippe Mathieu-Daudé OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
12257eedcf7SPhilippe Mathieu-Daudé };
12357eedcf7SPhilippe Mathieu-Daudé
124761533fcSPhilippe Mathieu-Daudé #define gen_helper_0e1i(name, arg1, arg2) do { \
125ad75a51eSRichard Henderson gen_helper_##name(tcg_env, arg1, tcg_constant_i32(arg2)); \
126761533fcSPhilippe Mathieu-Daudé } while (0)
127761533fcSPhilippe Mathieu-Daudé
128761533fcSPhilippe Mathieu-Daudé #define gen_helper_1e0i(name, ret, arg1) do { \
129ad75a51eSRichard Henderson gen_helper_##name(ret, tcg_env, tcg_constant_i32(arg1)); \
130761533fcSPhilippe Mathieu-Daudé } while (0)
131761533fcSPhilippe Mathieu-Daudé
132761533fcSPhilippe Mathieu-Daudé #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
133ad75a51eSRichard Henderson gen_helper_##name(tcg_env, arg1, arg2, tcg_constant_i32(arg3));\
134761533fcSPhilippe Mathieu-Daudé } while (0)
135761533fcSPhilippe Mathieu-Daudé
13646c9e2b3SPhilippe Mathieu-Daudé void generate_exception(DisasContext *ctx, int excp);
13746c9e2b3SPhilippe Mathieu-Daudé void generate_exception_err(DisasContext *ctx, int excp, int err);
13846c9e2b3SPhilippe Mathieu-Daudé void generate_exception_end(DisasContext *ctx, int excp);
1396f3533ddSRichard Henderson void generate_exception_break(DisasContext *ctx, int code);
1403a4ef3b7SPhilippe Mathieu-Daudé void gen_reserved_instruction(DisasContext *ctx);
14146c9e2b3SPhilippe Mathieu-Daudé
14246c9e2b3SPhilippe Mathieu-Daudé void check_insn(DisasContext *ctx, uint64_t flags);
14346c9e2b3SPhilippe Mathieu-Daudé void check_mips_64(DisasContext *ctx);
144905bdf72SPhilippe Mathieu-Daudé /**
145905bdf72SPhilippe Mathieu-Daudé * check_cp0_enabled:
146905bdf72SPhilippe Mathieu-Daudé * Return %true if CP0 is enabled, otherwise return %false
147905bdf72SPhilippe Mathieu-Daudé * and emit a 'coprocessor unusable' exception.
148905bdf72SPhilippe Mathieu-Daudé */
149905bdf72SPhilippe Mathieu-Daudé bool check_cp0_enabled(DisasContext *ctx);
1508758d1b8SPhilippe Mathieu-Daudé void check_cp1_enabled(DisasContext *ctx);
1518758d1b8SPhilippe Mathieu-Daudé void check_cp1_64bitmode(DisasContext *ctx);
1528758d1b8SPhilippe Mathieu-Daudé void check_cp1_registers(DisasContext *ctx, int regs);
1538758d1b8SPhilippe Mathieu-Daudé void check_cop1x(DisasContext *ctx);
15446c9e2b3SPhilippe Mathieu-Daudé
15546c9e2b3SPhilippe Mathieu-Daudé void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset);
15646c9e2b3SPhilippe Mathieu-Daudé void gen_move_low32(TCGv ret, TCGv_i64 arg);
15746c9e2b3SPhilippe Mathieu-Daudé void gen_move_high32(TCGv ret, TCGv_i64 arg);
15846c9e2b3SPhilippe Mathieu-Daudé void gen_load_gpr(TCGv t, int reg);
15946c9e2b3SPhilippe Mathieu-Daudé void gen_store_gpr(TCGv t, int reg);
16061f4e0ecSPhilippe Mathieu-Daudé #if defined(TARGET_MIPS64)
16161f4e0ecSPhilippe Mathieu-Daudé void gen_load_gpr_hi(TCGv_i64 t, int reg);
16261f4e0ecSPhilippe Mathieu-Daudé void gen_store_gpr_hi(TCGv_i64 t, int reg);
16361f4e0ecSPhilippe Mathieu-Daudé #endif /* TARGET_MIPS64 */
1648758d1b8SPhilippe Mathieu-Daudé void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg);
1658758d1b8SPhilippe Mathieu-Daudé void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
1668758d1b8SPhilippe Mathieu-Daudé void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg);
1678758d1b8SPhilippe Mathieu-Daudé void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
1688758d1b8SPhilippe Mathieu-Daudé int get_fp_bit(int cc);
16946c9e2b3SPhilippe Mathieu-Daudé
170d5076631SPhilippe Mathieu-Daudé void gen_ldxs(DisasContext *ctx, int base, int index, int rd);
171d5076631SPhilippe Mathieu-Daudé void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp);
172d5076631SPhilippe Mathieu-Daudé void gen_addiupc(DisasContext *ctx, int rx, int imm,
173d5076631SPhilippe Mathieu-Daudé int is_64_bit, int extended);
174d5076631SPhilippe Mathieu-Daudé
175a685f7d0SPhilippe Mathieu-Daudé /*
176a685f7d0SPhilippe Mathieu-Daudé * Address Computation and Large Constant Instructions
177a685f7d0SPhilippe Mathieu-Daudé */
17846c9e2b3SPhilippe Mathieu-Daudé void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1);
179d0b24b7fSPhilippe Mathieu-Daudé void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, target_long ofs);
180a685f7d0SPhilippe Mathieu-Daudé bool gen_lsa(DisasContext *ctx, int rd, int rt, int rs, int sa);
181a685f7d0SPhilippe Mathieu-Daudé bool gen_dlsa(DisasContext *ctx, int rd, int rt, int rs, int sa);
18246c9e2b3SPhilippe Mathieu-Daudé
183f9fa53f1SPhilippe Mathieu-Daudé void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel);
184f9fa53f1SPhilippe Mathieu-Daudé
18546c9e2b3SPhilippe Mathieu-Daudé extern TCGv cpu_gpr[32], cpu_PC;
186cefd68f6SPhilippe Mathieu-Daudé #if defined(TARGET_MIPS64)
187cefd68f6SPhilippe Mathieu-Daudé extern TCGv_i64 cpu_gpr_hi[32];
188cefd68f6SPhilippe Mathieu-Daudé #endif
1899f5f7691SPhilippe Mathieu-Daudé extern TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1908758d1b8SPhilippe Mathieu-Daudé extern TCGv_i32 fpu_fcr0, fpu_fcr31;
1918758d1b8SPhilippe Mathieu-Daudé extern TCGv_i64 fpu_f64[32];
19246c9e2b3SPhilippe Mathieu-Daudé extern TCGv bcond;
19346c9e2b3SPhilippe Mathieu-Daudé
19446c9e2b3SPhilippe Mathieu-Daudé #define LOG_DISAS(...) \
19546c9e2b3SPhilippe Mathieu-Daudé do { \
19646c9e2b3SPhilippe Mathieu-Daudé if (MIPS_DEBUG_DISAS) { \
19746c9e2b3SPhilippe Mathieu-Daudé qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
19846c9e2b3SPhilippe Mathieu-Daudé } \
19946c9e2b3SPhilippe Mathieu-Daudé } while (0)
20046c9e2b3SPhilippe Mathieu-Daudé
20146c9e2b3SPhilippe Mathieu-Daudé #define MIPS_INVAL(op) \
20246c9e2b3SPhilippe Mathieu-Daudé do { \
20346c9e2b3SPhilippe Mathieu-Daudé if (MIPS_DEBUG_DISAS) { \
20446c9e2b3SPhilippe Mathieu-Daudé qemu_log_mask(CPU_LOG_TB_IN_ASM, \
20585c19af6SAnton Johansson "%016" VADDR_PRIx \
20685c19af6SAnton Johansson ": %08x Invalid %s %03x %03x %03x\n", \
20746c9e2b3SPhilippe Mathieu-Daudé ctx->base.pc_next, ctx->opcode, op, \
20846c9e2b3SPhilippe Mathieu-Daudé ctx->opcode >> 26, ctx->opcode & 0x3F, \
20946c9e2b3SPhilippe Mathieu-Daudé ((ctx->opcode >> 16) & 0x1F)); \
21046c9e2b3SPhilippe Mathieu-Daudé } \
21146c9e2b3SPhilippe Mathieu-Daudé } while (0)
21246c9e2b3SPhilippe Mathieu-Daudé
213959c5da2SPhilippe Mathieu-Daudé /* MSA */
214959c5da2SPhilippe Mathieu-Daudé void msa_translate_init(void);
215959c5da2SPhilippe Mathieu-Daudé
216c7abe00aSPhilippe Mathieu-Daudé /* MXU */
217fe35ea94SPhilippe Mathieu-Daudé void mxu_translate_init(void);
218c7abe00aSPhilippe Mathieu-Daudé bool decode_ase_mxu(DisasContext *ctx, uint32_t insn);
219c7abe00aSPhilippe Mathieu-Daudé
2201b63c0b7SPhilippe Mathieu-Daudé bool decode_64bit_enabled(DisasContext *ctx);
2211b63c0b7SPhilippe Mathieu-Daudé
222c7a9ef75SPhilippe Mathieu-Daudé /* decodetree generated */
2233f7a9278SPhilippe Mathieu-Daudé bool decode_isa_rel6(DisasContext *ctx, uint32_t insn);
224c7a9ef75SPhilippe Mathieu-Daudé bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
225ffc672aaSPhilippe Mathieu-Daudé bool decode_ext_txx9(DisasContext *ctx, uint32_t insn);
2262cb26746SPhilippe Mathieu-Daudé bool decode_ext_loongson(DisasContext *ctx, uint32_t insn);
227ffc672aaSPhilippe Mathieu-Daudé #if defined(TARGET_MIPS64)
22803afdc28SJiaxun Yang bool decode_ase_lcsr(DisasContext *ctx, uint32_t insn);
229ffc672aaSPhilippe Mathieu-Daudé bool decode_ext_tx79(DisasContext *ctx, uint32_t insn);
23072d680e4SPavel Dovgalyuk bool decode_ext_octeon(DisasContext *ctx, uint32_t insn);
231ffc672aaSPhilippe Mathieu-Daudé #endif
2329d005392SPhilippe Mathieu-Daudé bool decode_ext_vr54xx(DisasContext *ctx, uint32_t insn);
233c7a9ef75SPhilippe Mathieu-Daudé
disas_mt_available(DisasContext * ctx)234*804607e8SPhilippe Mathieu-Daudé static inline bool disas_mt_available(DisasContext *ctx)
235*804607e8SPhilippe Mathieu-Daudé {
236*804607e8SPhilippe Mathieu-Daudé return ctx->CP0_Config3 & (1 << CP0C3_MT);
237*804607e8SPhilippe Mathieu-Daudé }
238*804607e8SPhilippe Mathieu-Daudé
239fb3164e4SPhilippe Mathieu-Daudé /*
240fb3164e4SPhilippe Mathieu-Daudé * Helpers for implementing sets of trans_* functions.
241fb3164e4SPhilippe Mathieu-Daudé * Defer the implementation of NAME to FUNC, with optional extra arguments.
242fb3164e4SPhilippe Mathieu-Daudé */
243fb3164e4SPhilippe Mathieu-Daudé #define TRANS(NAME, FUNC, ...) \
244fb3164e4SPhilippe Mathieu-Daudé static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
245fb3164e4SPhilippe Mathieu-Daudé { return FUNC(ctx, a, __VA_ARGS__); }
246fb3164e4SPhilippe Mathieu-Daudé
disas_is_bigendian(DisasContext * ctx)247e99072b6SPhilippe Mathieu-Daudé static inline bool disas_is_bigendian(DisasContext *ctx)
248bf78469cSPhilippe Mathieu-Daudé {
249bf78469cSPhilippe Mathieu-Daudé return extract32(ctx->CP0_Config0, CP0C0_BE, 1);
250bf78469cSPhilippe Mathieu-Daudé }
251bf78469cSPhilippe Mathieu-Daudé
mo_endian(DisasContext * dc)25296ccd853SPhilippe Mathieu-Daudé static inline MemOp mo_endian(DisasContext *dc)
25396ccd853SPhilippe Mathieu-Daudé {
25496ccd853SPhilippe Mathieu-Daudé return disas_is_bigendian(dc) ? MO_BE : MO_LE;
25596ccd853SPhilippe Mathieu-Daudé }
25696ccd853SPhilippe Mathieu-Daudé
mo_endian_rev(DisasContext * dc,bool reversed)257e9c26e77SPhilippe Mathieu-Daudé static inline MemOp mo_endian_rev(DisasContext *dc, bool reversed)
258e9c26e77SPhilippe Mathieu-Daudé {
259e9c26e77SPhilippe Mathieu-Daudé return disas_is_bigendian(dc) ^ reversed ? MO_BE : MO_LE;
260e9c26e77SPhilippe Mathieu-Daudé }
261e9c26e77SPhilippe Mathieu-Daudé
262e3130936SPhilippe Mathieu-Daudé #endif
263