Skip to content

Commit 2551c65

Browse files
[ppc64le] Added float32 support and implemented all R4 opcodes (#86092)
* [ppc64le] Fixed thunk address 8 byte alignment issue * Fixed FSharp crash issue * [ppc64le] Implementation of mono_arch_get_delegate_virtual_invoke_impl method for ppc64le architecture * Fixed clang15 build issues and returning address of sc_sp instead of value * Added float32 support and implemented related opcodes * Correction in OP_RCONV_TO_R cases * Corrected code for few opcodes
1 parent 7c3a572 commit 2551c65

File tree

4 files changed

+88
-8
lines changed

4 files changed

+88
-8
lines changed

src/mono/mono/arch/ppc/ppc-codegen.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,10 @@ my and Ximian's copyright to this code. ;)
793793
#define ppc_fcfid(c,D,B) ppc_fcfidx(c,D,B,0)
794794
#define ppc_fcfidd(c,D,B) ppc_fcfidx(c,D,B,1)
795795

796+
#define ppc_fcfidsx(c,D,B,Rc) ppc_emit32(c, (59 << 26) | ((D) << 21) | (0 << 16) | ((B) << 11) | (846 << 1) | (Rc))
797+
#define ppc_fcfids(c,D,B) ppc_fcfidsx(c,D,B,0)
798+
#define ppc_fcfidsd(c,D,B) ppc_fcfidsx(c,D,B,1)
799+
796800
#define ppc_fctidx(c,D,B,Rc) ppc_emit32(c, (63 << 26) | ((D) << 21) | (0 << 16) | ((B) << 11) | (814 << 1) | (Rc))
797801
#define ppc_fctid(c,D,B) ppc_fctidx(c,D,B,0)
798802
#define ppc_fctidd(c,D,B) ppc_fctidx(c,D,B,1)

src/mono/mono/mini/cpu-ppc64.mdesc

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,37 @@ ppc_subfze: dest:i src1:i len:4
229229
bigmul: len:12 dest:i src1:i src2:i
230230
bigmul_un: len:12 dest:i src1:i src2:i
231231

232+
# R4 opcodes
233+
r4_conv_to_i1: dest:i src1:f len:40
234+
r4_conv_to_u1: dest:i src1:f len:40
235+
r4_conv_to_i2: dest:i src1:f len:40
236+
r4_conv_to_u2: dest:i src1:f len:40
237+
r4_conv_to_i4: dest:i src1:f len:40
238+
r4_conv_to_u4: dest:i src1:f len:40
239+
r4_conv_to_i8: dest:i src1:f len:40
240+
r4_conv_to_u8: dest:i src1:f len:40
241+
r4_conv_to_r8: dest:f src1:f len:4
242+
r4_conv_to_r4: dest:f src1:f len:4
243+
r4_add: dest:f src1:f src2:f len:4
244+
r4_sub: dest:f src1:f src2:f len:4
245+
r4_mul: dest:f src1:f src2:f len:4
246+
r4_div: dest:f src1:f src2:f len:4
247+
r4_rem: dest:f src1:f src2:f len:16
248+
r4_neg: dest:f src1:f len:4
249+
r4_ceq: dest:i src1:f src2:f len:16
250+
r4_cgt: dest:i src1:f src2:f len:16
251+
r4_cgt_un: dest:i src1:f src2:f len:20
252+
r4_clt: dest:i src1:f src2:f len:16
253+
r4_clt_un: dest:i src1:f src2:f len:20
254+
r4_cneq: dest:i src1:f src2:f len:16
255+
r4_cge: dest:i src1:f src2:f len:16
256+
r4_cle: dest:i src1:f src2:f len:16
257+
rmove: dest:f src1:f len:4
258+
rcompare: src1:f src2:f len:12
259+
rcall_membase: dest:g src1:b len:16 clob:c
260+
rcall_reg: dest:g src1:i len:16 clob:c
261+
rcall: dest:g len:40 clob:c
262+
232263
# Linear IR opcodes
233264
dummy_use: src1:i len:0
234265
dummy_iconst: dest:i len:0
@@ -258,7 +289,7 @@ int_conv_to_i1: dest:i src1:i len:8
258289
int_conv_to_i2: dest:i src1:i len:8
259290
int_conv_to_i4: dest:i src1:i len:4
260291
sext_i4: dest:i src1:i len:4
261-
int_conv_to_r4: dest:f src1:i len:20
292+
int_conv_to_r4: dest:f src1:i len:16
262293
int_conv_to_r8: dest:f src1:i len:16
263294
int_conv_to_u4: dest:i src1:i len:4
264295
int_conv_to_u2: dest:i src1:i len:8
@@ -354,7 +385,7 @@ long_not: dest:i src1:i len:4
354385
long_conv_to_i1: dest:i src1:i len:4
355386
long_conv_to_i2: dest:i src1:i len:4
356387
long_conv_to_i4: dest:i src1:i len:4
357-
long_conv_to_r4: dest:f src1:i len:16
388+
long_conv_to_r4: dest:f src1:i len:12
358389
long_conv_to_r8: dest:f src1:i len:12
359390
long_conv_to_u4: dest:i src1:i
360391
long_conv_to_u2: dest:i src1:i len:4

src/mono/mono/mini/mini-ppc.c

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3033,8 +3033,11 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
30333033
{
30343034
switch (ins->opcode) {
30353035
case OP_FCALL:
3036+
case OP_RCALL:
30363037
case OP_FCALL_REG:
3038+
case OP_RCALL_REG:
30373039
case OP_FCALL_MEMBASE:
3040+
case OP_RCALL_MEMBASE:
30383041
if (ins->dreg != ppc_f1)
30393042
ppc_fmr (code, ins->dreg, ppc_f1);
30403043
break;
@@ -3763,6 +3766,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
37633766
ppc_mr (code, ppc_r4, saved);
37643767
break;
37653768
}
3769+
case OP_RMOVE:
37663770
case OP_FMOVE:
37673771
if (ins->dreg != ins->sreg1)
37683772
ppc_fmr (code, ins->dreg, ins->sreg1);
@@ -3894,6 +3898,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
38943898
ppc_stptr (code, ppc_r0, 0, ins->sreg1);
38953899
break;
38963900
}
3901+
case OP_RCALL:
38973902
case OP_FCALL:
38983903
case OP_LCALL:
38993904
case OP_VCALL:
@@ -3916,6 +3921,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
39163921
/* FIXME: this should be handled somewhere else in the new jit */
39173922
code = emit_move_return_value (cfg, ins, code);
39183923
break;
3924+
case OP_RCALL_REG:
39193925
case OP_FCALL_REG:
39203926
case OP_LCALL_REG:
39213927
case OP_VCALL_REG:
@@ -3945,6 +3951,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
39453951
/* FIXME: this should be handled somewhere else in the new jit */
39463952
code = emit_move_return_value (cfg, ins, code);
39473953
break;
3954+
case OP_RCALL_MEMBASE:
39483955
case OP_FCALL_MEMBASE:
39493956
case OP_LCALL_MEMBASE:
39503957
case OP_VCALL_MEMBASE:
@@ -4266,21 +4273,27 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
42664273
case CEE_CONV_R4: /* FIXME: change precision */
42674274
case CEE_CONV_R8:
42684275
g_assert_not_reached ();
4276+
case OP_RCONV_TO_I1:
42694277
case OP_FCONV_TO_I1:
42704278
code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 1, TRUE);
42714279
break;
4280+
case OP_RCONV_TO_U1:
42724281
case OP_FCONV_TO_U1:
42734282
code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 1, FALSE);
42744283
break;
4284+
case OP_RCONV_TO_I2:
42754285
case OP_FCONV_TO_I2:
42764286
code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 2, TRUE);
42774287
break;
4288+
case OP_RCONV_TO_U2:
42784289
case OP_FCONV_TO_U2:
42794290
code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 2, FALSE);
42804291
break;
4292+
case OP_RCONV_TO_I4:
42814293
case OP_FCONV_TO_I4:
42824294
code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, TRUE);
42834295
break;
4296+
case OP_RCONV_TO_U4:
42844297
case OP_FCONV_TO_U4:
42854298
code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, FALSE);
42864299
break;
@@ -4339,21 +4352,35 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
43394352
case OP_SQRT:
43404353
ppc_fsqrtd (code, ins->dreg, ins->sreg1);
43414354
break;
4355+
case OP_RADD:
4356+
ppc_fadds (code, ins->dreg, ins->sreg1, ins->sreg2);
4357+
break;
43424358
case OP_FADD:
43434359
ppc_fadd (code, ins->dreg, ins->sreg1, ins->sreg2);
43444360
break;
4361+
case OP_RSUB:
4362+
ppc_fsubs (code, ins->dreg, ins->sreg1, ins->sreg2);
4363+
break;
43454364
case OP_FSUB:
43464365
ppc_fsub (code, ins->dreg, ins->sreg1, ins->sreg2);
43474366
break;
4367+
case OP_RMUL:
4368+
ppc_fmuls (code, ins->dreg, ins->sreg1, ins->sreg2);
4369+
break;
43484370
case OP_FMUL:
43494371
ppc_fmul (code, ins->dreg, ins->sreg1, ins->sreg2);
43504372
break;
4373+
case OP_RDIV:
4374+
ppc_fdivs (code, ins->dreg, ins->sreg1, ins->sreg2);
4375+
break;
43514376
case OP_FDIV:
43524377
ppc_fdiv (code, ins->dreg, ins->sreg1, ins->sreg2);
43534378
break;
4379+
case OP_RNEG:
43544380
case OP_FNEG:
43554381
ppc_fneg (code, ins->dreg, ins->sreg1);
43564382
break;
4383+
case OP_RREM:
43574384
case OP_FREM:
43584385
/* emulated */
43594386
g_assert_not_reached ();
@@ -4391,37 +4418,46 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
43914418
ppc_cmpl (code, 0, 1, ins->sreg1, ins->sreg2);
43924419
ppc_iselgt (code, ins->dreg, ins->sreg1, ins->sreg2);
43934420
break;
4421+
case OP_RCOMPARE:
43944422
case OP_FCOMPARE:
43954423
ppc_fcmpu (code, 0, ins->sreg1, ins->sreg2);
43964424
break;
4425+
case OP_RCEQ:
4426+
case OP_RCNEQ:
43974427
case OP_FCEQ:
43984428
case OP_FCNEQ:
43994429
ppc_fcmpo (code, 0, ins->sreg1, ins->sreg2);
44004430
ppc_li (code, ins->dreg, 1);
4401-
ppc_bc (code, ins->opcode == OP_FCEQ ? PPC_BR_TRUE : PPC_BR_FALSE, PPC_BR_EQ, 2);
4431+
ppc_bc (code, ins->opcode == OP_FCEQ || ins->opcode == OP_RCEQ ? PPC_BR_TRUE : PPC_BR_FALSE, PPC_BR_EQ, 2);
44024432
ppc_li (code, ins->dreg, 0);
44034433
break;
4434+
case OP_RCLT:
4435+
case OP_RCGE:
44044436
case OP_FCLT:
44054437
case OP_FCGE:
44064438
ppc_fcmpo (code, 0, ins->sreg1, ins->sreg2);
44074439
ppc_li (code, ins->dreg, 1);
4408-
ppc_bc (code, ins->opcode == OP_FCLT ? PPC_BR_TRUE : PPC_BR_FALSE, PPC_BR_LT, 2);
4440+
ppc_bc (code, ins->opcode == OP_FCLT || ins->opcode == OP_RCLT ? PPC_BR_TRUE : PPC_BR_FALSE, PPC_BR_LT, 2);
44094441
ppc_li (code, ins->dreg, 0);
44104442
break;
4443+
case OP_RCLT_UN:
44114444
case OP_FCLT_UN:
44124445
ppc_fcmpu (code, 0, ins->sreg1, ins->sreg2);
44134446
ppc_li (code, ins->dreg, 1);
44144447
ppc_bc (code, PPC_BR_TRUE, PPC_BR_SO, 3);
44154448
ppc_bc (code, PPC_BR_TRUE, PPC_BR_LT, 2);
44164449
ppc_li (code, ins->dreg, 0);
44174450
break;
4451+
case OP_RCGT:
4452+
case OP_RCLE:
44184453
case OP_FCGT:
44194454
case OP_FCLE:
44204455
ppc_fcmpo (code, 0, ins->sreg1, ins->sreg2);
44214456
ppc_li (code, ins->dreg, 1);
4422-
ppc_bc (code, ins->opcode == OP_FCGT ? PPC_BR_TRUE : PPC_BR_FALSE, PPC_BR_GT, 2);
4457+
ppc_bc (code, ins->opcode == OP_FCGT || ins->opcode == OP_RCGT ? PPC_BR_TRUE : PPC_BR_FALSE, PPC_BR_GT, 2);
44234458
ppc_li (code, ins->dreg, 0);
44244459
break;
4460+
case OP_RCGT_UN:
44254461
case OP_FCGT_UN:
44264462
ppc_fcmpu (code, 0, ins->sreg1, ins->sreg2);
44274463
ppc_li (code, ins->dreg, 1);
@@ -4492,6 +4528,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
44924528
case OP_ZEXT_I4:
44934529
ppc_clrldi (code, ins->dreg, ins->sreg1, 32);
44944530
break;
4531+
case OP_RCONV_TO_R4:
4532+
case OP_RCONV_TO_R8:
4533+
ppc_fmr (code, ins->dreg, ins->sreg1);
4534+
break;
44954535
case OP_ICONV_TO_R4:
44964536
case OP_ICONV_TO_R8:
44974537
case OP_LCONV_TO_R4:
@@ -4509,9 +4549,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
45094549
ppc_str (code, tmp, -8, ppc_r1);
45104550
ppc_lfd (code, ins->dreg, -8, ppc_r1);
45114551
}
4512-
ppc_fcfid (code, ins->dreg, ins->dreg);
4513-
if (ins->opcode == OP_ICONV_TO_R4 || ins->opcode == OP_LCONV_TO_R4)
4514-
ppc_frsp (code, ins->dreg, ins->dreg);
4552+
if (ins->opcode == OP_ICONV_TO_R4 || ins->opcode == OP_LCONV_TO_R4) {
4553+
ppc_fcfids (code, ins->dreg, ins->dreg);
4554+
} else {
4555+
ppc_fcfid (code, ins->dreg, ins->dreg);
4556+
}
45154557
break;
45164558
}
45174559
case OP_LSHR:
@@ -4544,9 +4586,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
45444586
case OP_LBLE_UN:
45454587
EMIT_COND_BRANCH (ins, ins->opcode - OP_LBEQ);
45464588
break;
4589+
case OP_RCONV_TO_I8:
45474590
case OP_FCONV_TO_I8:
45484591
code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 8, TRUE);
45494592
break;
4593+
case OP_RCONV_TO_U8:
45504594
case OP_FCONV_TO_U8:
45514595
code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 8, FALSE);
45524596
break;

src/mono/mono/mini/mini-ppc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ typedef struct MonoCompileArch {
261261
#define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES 1
262262

263263
#define MONO_ARCH_GSHARED_SUPPORTED 1
264+
#define MONO_ARCH_FLOAT32_SUPPORTED 1
264265

265266
#define MONO_ARCH_NEED_DIV_CHECK 1
266267
#define MONO_ARCH_AOT_SUPPORTED 1

0 commit comments

Comments
 (0)