xref: /qemu/target/ppc/translate/dfp-impl.c.inc (revision 21d7826f)
1/*** Decimal Floating Point ***/
2
3static inline TCGv_ptr gen_fprp_ptr(int reg)
4{
5    TCGv_ptr r = tcg_temp_new_ptr();
6    tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, vsr[reg].u64[0]));
7    return r;
8}
9
10#define GEN_DFP_T_A_B_Rc(name)                   \
11static void gen_##name(DisasContext *ctx)        \
12{                                                \
13    TCGv_ptr rd, ra, rb;                         \
14    if (unlikely(!ctx->fpu_enabled)) {           \
15        gen_exception(ctx, POWERPC_EXCP_FPU);    \
16        return;                                  \
17    }                                            \
18    gen_update_nip(ctx, ctx->base.pc_next - 4);  \
19    rd = gen_fprp_ptr(rD(ctx->opcode));          \
20    ra = gen_fprp_ptr(rA(ctx->opcode));          \
21    rb = gen_fprp_ptr(rB(ctx->opcode));          \
22    gen_helper_##name(cpu_env, rd, ra, rb);      \
23    if (unlikely(Rc(ctx->opcode) != 0)) {        \
24        gen_set_cr1_from_fpscr(ctx);             \
25    }                                            \
26    tcg_temp_free_ptr(rd);                       \
27    tcg_temp_free_ptr(ra);                       \
28    tcg_temp_free_ptr(rb);                       \
29}
30
31#define GEN_DFP_BF_A_B(name)                      \
32static void gen_##name(DisasContext *ctx)         \
33{                                                 \
34    TCGv_ptr ra, rb;                              \
35    if (unlikely(!ctx->fpu_enabled)) {            \
36        gen_exception(ctx, POWERPC_EXCP_FPU);     \
37        return;                                   \
38    }                                             \
39    gen_update_nip(ctx, ctx->base.pc_next - 4);            \
40    ra = gen_fprp_ptr(rA(ctx->opcode));           \
41    rb = gen_fprp_ptr(rB(ctx->opcode));           \
42    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
43                      cpu_env, ra, rb);           \
44    tcg_temp_free_ptr(ra);                        \
45    tcg_temp_free_ptr(rb);                        \
46}
47
48#define GEN_DFP_BF_I_B(name)                      \
49static void gen_##name(DisasContext *ctx)         \
50{                                                 \
51    TCGv_i32 uim;                                 \
52    TCGv_ptr rb;                                  \
53    if (unlikely(!ctx->fpu_enabled)) {            \
54        gen_exception(ctx, POWERPC_EXCP_FPU);     \
55        return;                                   \
56    }                                             \
57    gen_update_nip(ctx, ctx->base.pc_next - 4);            \
58    uim = tcg_const_i32(UIMM5(ctx->opcode));      \
59    rb = gen_fprp_ptr(rB(ctx->opcode));           \
60    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
61                      cpu_env, uim, rb);          \
62    tcg_temp_free_i32(uim);                       \
63    tcg_temp_free_ptr(rb);                        \
64}
65
66#define GEN_DFP_BF_A_DCM(name)                    \
67static void gen_##name(DisasContext *ctx)         \
68{                                                 \
69    TCGv_ptr ra;                                  \
70    TCGv_i32 dcm;                                 \
71    if (unlikely(!ctx->fpu_enabled)) {            \
72        gen_exception(ctx, POWERPC_EXCP_FPU);     \
73        return;                                   \
74    }                                             \
75    gen_update_nip(ctx, ctx->base.pc_next - 4);   \
76    ra = gen_fprp_ptr(rA(ctx->opcode));           \
77    dcm = tcg_const_i32(DCM(ctx->opcode));        \
78    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
79                      cpu_env, ra, dcm);          \
80    tcg_temp_free_ptr(ra);                        \
81    tcg_temp_free_i32(dcm);                       \
82}
83
84#define GEN_DFP_T_B_U32_U32_Rc(name, u32f1, u32f2)    \
85static void gen_##name(DisasContext *ctx)             \
86{                                                     \
87    TCGv_ptr rt, rb;                                  \
88    TCGv_i32 u32_1, u32_2;                            \
89    if (unlikely(!ctx->fpu_enabled)) {                \
90        gen_exception(ctx, POWERPC_EXCP_FPU);         \
91        return;                                       \
92    }                                                 \
93    gen_update_nip(ctx, ctx->base.pc_next - 4);       \
94    rt = gen_fprp_ptr(rD(ctx->opcode));               \
95    rb = gen_fprp_ptr(rB(ctx->opcode));               \
96    u32_1 = tcg_const_i32(u32f1(ctx->opcode));        \
97    u32_2 = tcg_const_i32(u32f2(ctx->opcode));        \
98    gen_helper_##name(cpu_env, rt, rb, u32_1, u32_2); \
99    if (unlikely(Rc(ctx->opcode) != 0)) {             \
100        gen_set_cr1_from_fpscr(ctx);                  \
101    }                                                 \
102    tcg_temp_free_ptr(rt);                            \
103    tcg_temp_free_ptr(rb);                            \
104    tcg_temp_free_i32(u32_1);                         \
105    tcg_temp_free_i32(u32_2);                         \
106}
107
108#define GEN_DFP_T_A_B_I32_Rc(name, i32fld)       \
109static void gen_##name(DisasContext *ctx)        \
110{                                                \
111    TCGv_ptr rt, ra, rb;                         \
112    TCGv_i32 i32;                                \
113    if (unlikely(!ctx->fpu_enabled)) {           \
114        gen_exception(ctx, POWERPC_EXCP_FPU);    \
115        return;                                  \
116    }                                            \
117    gen_update_nip(ctx, ctx->base.pc_next - 4);  \
118    rt = gen_fprp_ptr(rD(ctx->opcode));          \
119    ra = gen_fprp_ptr(rA(ctx->opcode));          \
120    rb = gen_fprp_ptr(rB(ctx->opcode));          \
121    i32 = tcg_const_i32(i32fld(ctx->opcode));    \
122    gen_helper_##name(cpu_env, rt, ra, rb, i32); \
123    if (unlikely(Rc(ctx->opcode) != 0)) {        \
124        gen_set_cr1_from_fpscr(ctx);             \
125    }                                            \
126    tcg_temp_free_ptr(rt);                       \
127    tcg_temp_free_ptr(rb);                       \
128    tcg_temp_free_ptr(ra);                       \
129    tcg_temp_free_i32(i32);                      \
130    }
131
132#define GEN_DFP_T_B_Rc(name)                     \
133static void gen_##name(DisasContext *ctx)        \
134{                                                \
135    TCGv_ptr rt, rb;                             \
136    if (unlikely(!ctx->fpu_enabled)) {           \
137        gen_exception(ctx, POWERPC_EXCP_FPU);    \
138        return;                                  \
139    }                                            \
140    gen_update_nip(ctx, ctx->base.pc_next - 4);  \
141    rt = gen_fprp_ptr(rD(ctx->opcode));          \
142    rb = gen_fprp_ptr(rB(ctx->opcode));          \
143    gen_helper_##name(cpu_env, rt, rb);          \
144    if (unlikely(Rc(ctx->opcode) != 0)) {        \
145        gen_set_cr1_from_fpscr(ctx);             \
146    }                                            \
147    tcg_temp_free_ptr(rt);                       \
148    tcg_temp_free_ptr(rb);                       \
149    }
150
151#define GEN_DFP_T_FPR_I32_Rc(name, fprfld, i32fld) \
152static void gen_##name(DisasContext *ctx)          \
153{                                                  \
154    TCGv_ptr rt, rs;                               \
155    TCGv_i32 i32;                                  \
156    if (unlikely(!ctx->fpu_enabled)) {             \
157        gen_exception(ctx, POWERPC_EXCP_FPU);      \
158        return;                                    \
159    }                                              \
160    gen_update_nip(ctx, ctx->base.pc_next - 4);    \
161    rt = gen_fprp_ptr(rD(ctx->opcode));            \
162    rs = gen_fprp_ptr(fprfld(ctx->opcode));        \
163    i32 = tcg_const_i32(i32fld(ctx->opcode));      \
164    gen_helper_##name(cpu_env, rt, rs, i32);       \
165    if (unlikely(Rc(ctx->opcode) != 0)) {          \
166        gen_set_cr1_from_fpscr(ctx);               \
167    }                                              \
168    tcg_temp_free_ptr(rt);                         \
169    tcg_temp_free_ptr(rs);                         \
170    tcg_temp_free_i32(i32);                        \
171}
172
173GEN_DFP_T_A_B_Rc(dadd)
174GEN_DFP_T_A_B_Rc(daddq)
175GEN_DFP_T_A_B_Rc(dsub)
176GEN_DFP_T_A_B_Rc(dsubq)
177GEN_DFP_T_A_B_Rc(dmul)
178GEN_DFP_T_A_B_Rc(dmulq)
179GEN_DFP_T_A_B_Rc(ddiv)
180GEN_DFP_T_A_B_Rc(ddivq)
181GEN_DFP_BF_A_B(dcmpu)
182GEN_DFP_BF_A_B(dcmpuq)
183GEN_DFP_BF_A_B(dcmpo)
184GEN_DFP_BF_A_B(dcmpoq)
185GEN_DFP_BF_A_DCM(dtstdc)
186GEN_DFP_BF_A_DCM(dtstdcq)
187GEN_DFP_BF_A_DCM(dtstdg)
188GEN_DFP_BF_A_DCM(dtstdgq)
189GEN_DFP_BF_A_B(dtstex)
190GEN_DFP_BF_A_B(dtstexq)
191GEN_DFP_BF_A_B(dtstsf)
192GEN_DFP_BF_A_B(dtstsfq)
193GEN_DFP_BF_I_B(dtstsfi)
194GEN_DFP_BF_I_B(dtstsfiq)
195GEN_DFP_T_B_U32_U32_Rc(dquai, SIMM5, RMC)
196GEN_DFP_T_B_U32_U32_Rc(dquaiq, SIMM5, RMC)
197GEN_DFP_T_A_B_I32_Rc(dqua, RMC)
198GEN_DFP_T_A_B_I32_Rc(dquaq, RMC)
199GEN_DFP_T_A_B_I32_Rc(drrnd, RMC)
200GEN_DFP_T_A_B_I32_Rc(drrndq, RMC)
201GEN_DFP_T_B_U32_U32_Rc(drintx, FPW, RMC)
202GEN_DFP_T_B_U32_U32_Rc(drintxq, FPW, RMC)
203GEN_DFP_T_B_U32_U32_Rc(drintn, FPW, RMC)
204GEN_DFP_T_B_U32_U32_Rc(drintnq, FPW, RMC)
205GEN_DFP_T_B_Rc(dctdp)
206GEN_DFP_T_B_Rc(dctqpq)
207GEN_DFP_T_B_Rc(drsp)
208GEN_DFP_T_B_Rc(drdpq)
209GEN_DFP_T_B_Rc(dcffix)
210GEN_DFP_T_B_Rc(dcffixq)
211GEN_DFP_T_B_Rc(dctfix)
212GEN_DFP_T_B_Rc(dctfixq)
213GEN_DFP_T_FPR_I32_Rc(ddedpd, rB, SP)
214GEN_DFP_T_FPR_I32_Rc(ddedpdq, rB, SP)
215GEN_DFP_T_FPR_I32_Rc(denbcd, rB, SP)
216GEN_DFP_T_FPR_I32_Rc(denbcdq, rB, SP)
217GEN_DFP_T_B_Rc(dxex)
218GEN_DFP_T_B_Rc(dxexq)
219GEN_DFP_T_A_B_Rc(diex)
220GEN_DFP_T_A_B_Rc(diexq)
221GEN_DFP_T_FPR_I32_Rc(dscli, rA, DCM)
222GEN_DFP_T_FPR_I32_Rc(dscliq, rA, DCM)
223GEN_DFP_T_FPR_I32_Rc(dscri, rA, DCM)
224GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
225
226#undef GEN_DFP_T_A_B_Rc
227#undef GEN_DFP_BF_A_B
228#undef GEN_DFP_BF_A_DCM
229#undef GEN_DFP_T_B_U32_U32_Rc
230#undef GEN_DFP_T_A_B_I32_Rc
231#undef GEN_DFP_T_B_Rc
232#undef GEN_DFP_T_FPR_I32_Rc
233
234static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ *a)
235{
236    TCGv_ptr rt, rb;
237
238    REQUIRE_INSNS_FLAGS2(ctx, DFP);
239    REQUIRE_FPU(ctx);
240    REQUIRE_VECTOR(ctx);
241
242    rt = gen_fprp_ptr(a->frtp);
243    rb = gen_avr_ptr(a->vrb);
244    gen_helper_DCFFIXQQ(cpu_env, rt, rb);
245    tcg_temp_free_ptr(rt);
246    tcg_temp_free_ptr(rb);
247
248    return true;
249}
250