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