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 TRANS_DFP_T_A_B_Rc(NAME)                             \
11static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)   \
12{                                                            \
13    TCGv_ptr rt, ra, rb;                                     \
14    REQUIRE_INSNS_FLAGS2(ctx, DFP);                          \
15    REQUIRE_FPU(ctx);                                        \
16    rt = gen_fprp_ptr(a->rt);                                \
17    ra = gen_fprp_ptr(a->ra);                                \
18    rb = gen_fprp_ptr(a->rb);                                \
19    gen_helper_##NAME(cpu_env, rt, ra, rb);                  \
20    if (unlikely(a->rc)) {                                   \
21        gen_set_cr1_from_fpscr(ctx);                         \
22    }                                                        \
23    tcg_temp_free_ptr(rt);                                   \
24    tcg_temp_free_ptr(ra);                                   \
25    tcg_temp_free_ptr(rb);                                   \
26    return true;                                             \
27}
28
29#define TRANS_DFP_BF_A_B(NAME)                               \
30static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)   \
31{                                                            \
32    TCGv_ptr ra, rb;                                         \
33    REQUIRE_INSNS_FLAGS2(ctx, DFP);                          \
34    REQUIRE_FPU(ctx);                                        \
35    ra = gen_fprp_ptr(a->ra);                                \
36    rb = gen_fprp_ptr(a->rb);                                \
37    gen_helper_##NAME(cpu_crf[a->bf],                        \
38                      cpu_env, ra, rb);                      \
39    tcg_temp_free_ptr(ra);                                   \
40    tcg_temp_free_ptr(rb);                                   \
41    return true;                                             \
42}
43
44#define TRANS_DFP_BF_I_B(NAME)                               \
45static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)   \
46{                                                            \
47    TCGv_ptr rb;                                             \
48    REQUIRE_INSNS_FLAGS2(ctx, DFP);                          \
49    REQUIRE_FPU(ctx);                                        \
50    rb = gen_fprp_ptr(a->rb);                                \
51    gen_helper_##NAME(cpu_crf[a->bf],                        \
52                      cpu_env, tcg_constant_i32(a->uim), rb);\
53    tcg_temp_free_ptr(rb);                                   \
54    return true;                                             \
55}
56
57#define TRANS_DFP_BF_A_DCM(NAME)                             \
58static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)   \
59{                                                            \
60    TCGv_ptr ra;                                             \
61    REQUIRE_INSNS_FLAGS2(ctx, DFP);                          \
62    REQUIRE_FPU(ctx);                                        \
63    ra = gen_fprp_ptr(a->fra);                               \
64    gen_helper_##NAME(cpu_crf[a->bf],                        \
65                      cpu_env, ra, tcg_constant_i32(a->dm)); \
66    tcg_temp_free_ptr(ra);                                   \
67    return true;                                             \
68}
69
70#define TRANS_DFP_T_B_U32_U32_Rc(NAME, U32F1, U32F2)         \
71static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)   \
72{                                                            \
73    TCGv_ptr rt, rb;                                         \
74    REQUIRE_INSNS_FLAGS2(ctx, DFP);                          \
75    REQUIRE_FPU(ctx);                                        \
76    rt = gen_fprp_ptr(a->frt);                               \
77    rb = gen_fprp_ptr(a->frb);                               \
78    gen_helper_##NAME(cpu_env, rt, rb,                       \
79                      tcg_constant_i32(a->U32F1),            \
80                      tcg_constant_i32(a->U32F2));           \
81    if (unlikely(a->rc)) {                                   \
82        gen_set_cr1_from_fpscr(ctx);                         \
83    }                                                        \
84    tcg_temp_free_ptr(rt);                                   \
85    tcg_temp_free_ptr(rb);                                   \
86    return true;                                             \
87}
88
89#define TRANS_DFP_T_A_B_I32_Rc(NAME, I32FLD)                 \
90static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)   \
91{                                                            \
92    TCGv_ptr rt, ra, rb;                                     \
93    REQUIRE_INSNS_FLAGS2(ctx, DFP);                          \
94    REQUIRE_FPU(ctx);                                        \
95    rt = gen_fprp_ptr(a->frt);                               \
96    ra = gen_fprp_ptr(a->fra);                               \
97    rb = gen_fprp_ptr(a->frb);                               \
98    gen_helper_##NAME(cpu_env, rt, ra, rb,                   \
99                      tcg_constant_i32(a->I32FLD));          \
100    if (unlikely(a->rc)) {                                   \
101        gen_set_cr1_from_fpscr(ctx);                         \
102    }                                                        \
103    tcg_temp_free_ptr(rt);                                   \
104    tcg_temp_free_ptr(ra);                                   \
105    tcg_temp_free_ptr(rb);                                   \
106    return true;                                             \
107}
108
109#define TRANS_DFP_T_B_Rc(NAME)                               \
110static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)   \
111{                                                            \
112    TCGv_ptr rt, rb;                                         \
113    REQUIRE_INSNS_FLAGS2(ctx, DFP);                          \
114    REQUIRE_FPU(ctx);                                        \
115    rt = gen_fprp_ptr(a->rt);                                \
116    rb = gen_fprp_ptr(a->rb);                                \
117    gen_helper_##NAME(cpu_env, rt, rb);                      \
118    if (unlikely(a->rc)) {                                   \
119        gen_set_cr1_from_fpscr(ctx);                         \
120    }                                                        \
121    tcg_temp_free_ptr(rt);                                   \
122    tcg_temp_free_ptr(rb);                                   \
123    return true;                                             \
124}
125
126#define TRANS_DFP_T_FPR_I32_Rc(NAME, FPRFLD, I32FLD)         \
127static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)   \
128{                                                            \
129    TCGv_ptr rt, rx;                                         \
130    REQUIRE_INSNS_FLAGS2(ctx, DFP);                          \
131    REQUIRE_FPU(ctx);                                        \
132    rt = gen_fprp_ptr(a->rt);                                \
133    rx = gen_fprp_ptr(a->FPRFLD);                            \
134    gen_helper_##NAME(cpu_env, rt, rx,                       \
135                      tcg_constant_i32(a->I32FLD));          \
136    if (unlikely(a->rc)) {                                   \
137        gen_set_cr1_from_fpscr(ctx);                         \
138    }                                                        \
139    tcg_temp_free_ptr(rt);                                   \
140    tcg_temp_free_ptr(rx);                                   \
141    return true;                                             \
142}
143
144TRANS_DFP_T_A_B_Rc(DADD)
145TRANS_DFP_T_A_B_Rc(DADDQ)
146TRANS_DFP_T_A_B_Rc(DSUB)
147TRANS_DFP_T_A_B_Rc(DSUBQ)
148TRANS_DFP_T_A_B_Rc(DMUL)
149TRANS_DFP_T_A_B_Rc(DMULQ)
150TRANS_DFP_T_A_B_Rc(DDIV)
151TRANS_DFP_T_A_B_Rc(DDIVQ)
152TRANS_DFP_BF_A_B(DCMPU)
153TRANS_DFP_BF_A_B(DCMPUQ)
154TRANS_DFP_BF_A_B(DCMPO)
155TRANS_DFP_BF_A_B(DCMPOQ)
156TRANS_DFP_BF_A_DCM(DTSTDC)
157TRANS_DFP_BF_A_DCM(DTSTDCQ)
158TRANS_DFP_BF_A_DCM(DTSTDG)
159TRANS_DFP_BF_A_DCM(DTSTDGQ)
160TRANS_DFP_BF_A_B(DTSTEX)
161TRANS_DFP_BF_A_B(DTSTEXQ)
162TRANS_DFP_BF_A_B(DTSTSF)
163TRANS_DFP_BF_A_B(DTSTSFQ)
164TRANS_DFP_BF_I_B(DTSTSFI)
165TRANS_DFP_BF_I_B(DTSTSFIQ)
166TRANS_DFP_T_B_U32_U32_Rc(DQUAI, te, rmc)
167TRANS_DFP_T_B_U32_U32_Rc(DQUAIQ, te, rmc)
168TRANS_DFP_T_A_B_I32_Rc(DQUA, rmc)
169TRANS_DFP_T_A_B_I32_Rc(DQUAQ, rmc)
170TRANS_DFP_T_A_B_I32_Rc(DRRND, rmc)
171TRANS_DFP_T_A_B_I32_Rc(DRRNDQ, rmc)
172TRANS_DFP_T_B_U32_U32_Rc(DRINTX, r, rmc)
173TRANS_DFP_T_B_U32_U32_Rc(DRINTXQ, r, rmc)
174TRANS_DFP_T_B_U32_U32_Rc(DRINTN, r, rmc)
175TRANS_DFP_T_B_U32_U32_Rc(DRINTNQ, r, rmc)
176TRANS_DFP_T_B_Rc(DCTDP)
177TRANS_DFP_T_B_Rc(DCTQPQ)
178TRANS_DFP_T_B_Rc(DRSP)
179TRANS_DFP_T_B_Rc(DRDPQ)
180TRANS_DFP_T_B_Rc(DCFFIX)
181TRANS_DFP_T_B_Rc(DCFFIXQ)
182TRANS_DFP_T_B_Rc(DCTFIX)
183TRANS_DFP_T_B_Rc(DCTFIXQ)
184TRANS_DFP_T_FPR_I32_Rc(DDEDPD, rb, sp)
185TRANS_DFP_T_FPR_I32_Rc(DDEDPDQ, rb, sp)
186TRANS_DFP_T_FPR_I32_Rc(DENBCD, rb, s)
187TRANS_DFP_T_FPR_I32_Rc(DENBCDQ, rb, s)
188TRANS_DFP_T_B_Rc(DXEX)
189TRANS_DFP_T_B_Rc(DXEXQ)
190TRANS_DFP_T_A_B_Rc(DIEX)
191TRANS_DFP_T_A_B_Rc(DIEXQ)
192TRANS_DFP_T_FPR_I32_Rc(DSCLI, ra, sh)
193TRANS_DFP_T_FPR_I32_Rc(DSCLIQ, ra, sh)
194TRANS_DFP_T_FPR_I32_Rc(DSCRI, ra, sh)
195TRANS_DFP_T_FPR_I32_Rc(DSCRIQ, ra, sh)
196
197static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ *a)
198{
199    TCGv_ptr rt, rb;
200
201    REQUIRE_INSNS_FLAGS2(ctx, DFP);
202    REQUIRE_FPU(ctx);
203    REQUIRE_VECTOR(ctx);
204
205    rt = gen_fprp_ptr(a->frtp);
206    rb = gen_avr_ptr(a->vrb);
207    gen_helper_DCFFIXQQ(cpu_env, rt, rb);
208    tcg_temp_free_ptr(rt);
209    tcg_temp_free_ptr(rb);
210
211    return true;
212}
213
214static bool trans_DCTFIXQQ(DisasContext *ctx, arg_DCTFIXQQ *a)
215{
216    TCGv_ptr rt, rb;
217
218    REQUIRE_INSNS_FLAGS2(ctx, DFP);
219    REQUIRE_FPU(ctx);
220    REQUIRE_VECTOR(ctx);
221
222    rt = gen_avr_ptr(a->vrt);
223    rb = gen_fprp_ptr(a->frbp);
224    gen_helper_DCTFIXQQ(cpu_env, rt, rb);
225    tcg_temp_free_ptr(rt);
226    tcg_temp_free_ptr(rb);
227
228    return true;
229}
230