@@ -488,6 +488,121 @@ emit_unsafe_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignatu
488
488
EMIT_NEW_BIALU (cfg , ins , OP_COMPARE , -1 , args [0 ]-> dreg , args [1 ]-> dreg );
489
489
EMIT_NEW_UNALU (cfg , ins , OP_PCEQ , dreg , -1 );
490
490
return ins ;
491
+ } else if (!strcmp (cmethod -> name , "BitCast" )) {
492
+ g_assert (ctx );
493
+ g_assert (ctx -> method_inst );
494
+ g_assert (ctx -> method_inst -> type_argc == 2 );
495
+ g_assert (fsig -> param_count == 1 );
496
+
497
+ MonoType * tfrom = ctx -> method_inst -> type_argv [0 ];
498
+ if (mini_is_gsharedvt_variable_type (tfrom )) {
499
+ // FIXME: Handle gsharevt
500
+ return NULL ;
501
+ }
502
+
503
+ MonoTypeEnum tfrom_type = tfrom -> type ;
504
+ MonoClass * tfrom_klass = mono_class_from_mono_type_internal (tfrom );
505
+ if (!m_class_is_valuetype (tfrom_klass )) {
506
+ return NULL ;
507
+ }
508
+
509
+ MonoType * tto = ctx -> method_inst -> type_argv [1 ];
510
+ if (mini_is_gsharedvt_variable_type (tto )) {
511
+ // FIXME: Handle gsharevt
512
+ return NULL ;
513
+ }
514
+
515
+ MonoTypeEnum tto_type = tto -> type ;
516
+ MonoClass * tto_klass = mono_class_from_mono_type_internal (tto );
517
+ if (!m_class_is_valuetype (tto_klass )) {
518
+ return NULL ;
519
+ }
520
+
521
+ int tfrom_align , tto_align ;
522
+ if (mono_type_size (tfrom , & tfrom_align ) != mono_type_size (tto , & tto_align )) {
523
+ return NULL ;
524
+ }
525
+
526
+ guint32 opcode = OP_LDADDR ;
527
+ MonoStackType tfrom_stack = STACK_PTR ;
528
+ MonoStackType tto_stack = STACK_OBJ ;
529
+
530
+ if (tfrom_type == MONO_TYPE_I4 ) {
531
+ if (tto_type == MONO_TYPE_R4 ) {
532
+ opcode = OP_MOVE_I4_TO_F ;
533
+ tfrom_stack = STACK_I4 ;
534
+ tto_stack = STACK_R4 ;
535
+ }
536
+ else if (tfrom_type == MONO_TYPE_I4 ) {
537
+ opcode = OP_MOVE ;
538
+ tfrom_stack = STACK_I4 ;
539
+ tto_stack = STACK_I4 ;
540
+ }
541
+ }
542
+ else if (tfrom_type == MONO_TYPE_I8 ) {
543
+ if (tto_type == MONO_TYPE_R8 ) {
544
+ opcode = OP_MOVE_I8_TO_F ;
545
+ tfrom_stack = STACK_I8 ;
546
+ tto_stack = STACK_R8 ;
547
+ }
548
+ else if (tfrom_type == MONO_TYPE_I8 ) {
549
+ opcode = OP_MOVE ;
550
+ tfrom_stack = STACK_I8 ;
551
+ tto_stack = STACK_I8 ;
552
+ }
553
+ }
554
+ else if (tfrom_type == MONO_TYPE_R4 ) {
555
+ if (tto_type == MONO_TYPE_I4 ) {
556
+ opcode = OP_MOVE_F_TO_I4 ;
557
+ tfrom_stack = STACK_R4 ;
558
+ tto_stack = STACK_I4 ;
559
+ }
560
+ else if (tto_type == MONO_TYPE_R4 ) {
561
+ opcode = OP_RMOVE ;
562
+ tfrom_stack = STACK_R4 ;
563
+ tto_stack = STACK_R4 ;
564
+ }
565
+ }
566
+ else if (tfrom_type == MONO_TYPE_R8 ) {
567
+ if (tto_type == MONO_TYPE_I8 ) {
568
+ opcode = OP_MOVE_F_TO_I8 ;
569
+ tfrom_stack = STACK_R8 ;
570
+ tto_stack = STACK_I8 ;
571
+ }
572
+ else if (tto_type == MONO_TYPE_R8 ) {
573
+ opcode = OP_FMOVE ;
574
+ tfrom_stack = STACK_R8 ;
575
+ tto_stack = STACK_R8 ;
576
+ }
577
+ }
578
+ else if (mini_class_is_simd (cfg , tfrom_klass )) {
579
+ if (mini_class_is_simd (cfg , tto_klass )) {
580
+ // FIXME: Ensure that SIMD to SIMD conversions can be handled
581
+ //
582
+ // opcode = OP_XMOVE;
583
+ // tfrom_stack = STACK_VTYPE;
584
+ // tto_stack = STACK_VTYPE;
585
+ }
586
+ }
587
+
588
+ if (opcode == OP_LDADDR ) {
589
+ MonoInst * arg0 ;
590
+ NEW_VARLOADA (cfg , arg0 , args [0 ], tfrom );
591
+ arg0 -> dreg = mono_alloc_preg (cfg );
592
+
593
+ tto = mini_get_underlying_type (tto );
594
+ assert (MONO_TYPE_ISSTRUCT (tto ));
595
+
596
+ if (cfg -> gshared && (tto != ctx -> method_inst -> type_argv [1 ]) && mono_class_check_context_used (mono_class_from_mono_type_internal (tto )))
597
+ cfg -> prefer_instances = TRUE;
598
+ return mini_emit_memory_load (cfg , tto , arg0 , 0 , MONO_INST_UNALIGNED );
599
+ }
600
+
601
+ int dreg = mono_alloc_dreg (cfg , tfrom_stack );
602
+ EMIT_NEW_UNALU (cfg , ins , opcode , dreg , args [0 ]-> dreg );
603
+ ins -> type = tto_stack ;
604
+ ins -> klass = tto_klass ;
605
+ return ins ;
491
606
} else if (!strcmp (cmethod -> name , "IsAddressLessThan" )) {
492
607
g_assert (ctx );
493
608
g_assert (ctx -> method_inst );
0 commit comments