Skip to content

Commit d86e911

Browse files
committed
Address some initial review feedback
1 parent a4ad71a commit d86e911

File tree

3 files changed

+74
-48
lines changed

3 files changed

+74
-48
lines changed

src/coreclr/jit/codegeninterface.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,9 @@ class CodeGenInterface
169169
private:
170170
#if defined(TARGET_XARCH)
171171
static const insFlags instInfo[INS_count];
172-
#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
172+
#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) || \
173+
defined(TARGET_WASM)
173174
static const BYTE instInfo[INS_count];
174-
#elif defined(TARGET_WASM)
175-
static const uint16_t instInfo[INS_count];
176175
#else
177176
#error Unsupported target architecture
178177
#endif

src/coreclr/jit/codegenwasm.cpp

Lines changed: 71 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,18 @@ static constexpr uint32_t PackOperAndType(genTreeOps oper, var_types toType, var
481481
return ((uint32_t)oper << shift1) | ((uint32_t)fromType) | ((uint32_t)toType << shift2);
482482
}
483483

484+
// ------------------------------------------------------------------------
485+
// PackTypes: Pack two var_types together into a uint32_t
486+
487+
// Arguments:
488+
// toType - a var_types to pack
489+
// fromType - a var_types to pack
490+
//
491+
// Return Value:
492+
// The two types packed together into an integer that can be used as a switch/value,
493+
// the primary use case being the handling of operations with two-type variants such
494+
// as casts.
495+
//
484496
static constexpr uint32_t PackTypes(var_types toType, var_types fromType)
485497
{
486498
if (toType == TYP_BYREF)
@@ -495,16 +507,26 @@ static constexpr uint32_t PackTypes(var_types toType, var_types fromType)
495507
return ((uint32_t)toType) | ((uint32_t)fromType << shift1);
496508
}
497509

510+
//------------------------------------------------------------------------
511+
// genIntToIntCast: Generate code for an integer to integer cast
512+
//
513+
// Arguments:
514+
// cast - The GT_CAST node for the integer cast operation
515+
//
516+
// Notes:
517+
// Handles casts to and from small int, int, and long types
518+
// including proper sign extension and truncation as needed.
519+
//
498520
void CodeGen::genIntToIntCast(GenTreeCast* cast)
499521
{
500522
GenIntCastDesc desc(cast);
501523
var_types toType = genActualType(cast->CastToType());
502-
var_types fromType = genActualType(cast->CastOp()->TypeGet());
524+
var_types fromType = genActualType(cast->CastOp());
503525
int extendSize = desc.ExtendSrcSize();
504526
instruction ins = INS_none;
505527
assert(fromType == TYP_INT || fromType == TYP_LONG);
506528

507-
genConsumeRegs(cast->CastOp());
529+
genConsumeOperands(cast);
508530

509531
switch (desc.ExtendKind())
510532
{
@@ -523,53 +545,31 @@ void CodeGen::genIntToIntCast(GenTreeCast* cast)
523545
}
524546
case GenIntCastDesc::ExtendKind::ZERO_EXTEND_SMALL_INT:
525547
{
526-
assert(extendSize <= 2);
527-
if (toType == TYP_LONG)
528-
{
529-
ins = INS_i64_extend_u_i32;
530-
}
531-
else
532-
{
533-
// We expect the underlying types to both be int here,
534-
// so we don't need to do anything more
535-
assert(toType == TYP_INT && fromType == TYP_INT);
536-
ins = INS_none;
537-
}
548+
int andAmount = extendSize == 1 ? 255 : 65535;
549+
GetEmitter()->emitIns_I(INS_i32_const, EA_4BYTE, andAmount);
550+
GetEmitter()->emitIns(INS_i32_and);
551+
ins = (toType == TYP_LONG) ? INS_i64_extend_u_i32 : INS_none;
538552
break;
539553
}
540554
case GenIntCastDesc::ExtendKind::SIGN_EXTEND_SMALL_INT:
541555
{
542-
assert(extendSize <= 2);
543-
switch (extendSize)
556+
if (fromType == TYP_LONG)
544557
{
545-
case 1:
546-
ins = INS_i32_extend8_s;
547-
break;
548-
case 2:
549-
ins = INS_i32_extend16_s;
550-
break;
551-
default:
552-
unreached();
558+
// the actual runtime type here could be a long, so first we need to
559+
// truncate it to int in that case
560+
GetEmitter()->emitIns(INS_i32_wrap_i64);
553561
}
562+
ins = (extendSize == 1) ? INS_i32_extend8_s : INS_i32_extend16_s;
554563

555-
// A sign-extended cast from small int->long requires two instructions; first sign extended
556-
// small int -> i32, then sign extended i32 -> i64
557-
if (toType == TYP_LONG)
558-
{
559-
GetEmitter()->emitIns(ins);
560-
ins = INS_i64_extend_s_i32;
561-
}
562564
break;
563565
}
564566
case GenIntCastDesc::ExtendKind::ZERO_EXTEND_INT:
565567
{
566-
assert(toType == TYP_LONG);
567568
ins = INS_i64_extend_u_i32;
568569
break;
569570
}
570571
case GenIntCastDesc::ExtendKind::SIGN_EXTEND_INT:
571572
{
572-
assert(toType == TYP_LONG);
573573
ins = INS_i64_extend_s_i32;
574574
break;
575575
}
@@ -584,28 +584,39 @@ void CodeGen::genIntToIntCast(GenTreeCast* cast)
584584
genProduceReg(cast);
585585
}
586586

587+
//------------------------------------------------------------------------
588+
// genFloatToIntCast: Generate code for a floating point to integer cast
589+
//
590+
// Arguments:
591+
// tree - The GT_CAST node for the float-to-int cast operation
592+
//
593+
// Notes:
594+
// Handles casts from TYP_FLOAT/TYP_DOUBLE to TYP_INT/TYP_LONG.
595+
// Uses saturating truncation instructions (trunc_sat) which clamp
596+
// out-of-range values rather than trapping.
597+
//
587598
void CodeGen::genFloatToIntCast(GenTree* tree)
588599
{
589-
var_types toType = genActualType(tree->TypeGet());
590-
var_types fromType = genActualType(tree->AsCast()->CastFromType());
600+
var_types toType = tree->TypeGet();
601+
var_types fromType = tree->AsCast()->CastOp()->TypeGet();
591602
bool isUnsigned = varTypeIsUnsigned(tree->AsCast()->CastToType());
592603
instruction ins = INS_none;
593604
assert(varTypeIsFloating(fromType) && (toType == TYP_INT || toType == TYP_LONG));
594605

595-
genConsumeRegs(tree->AsCast()->CastOp());
606+
genConsumeOperands(tree->AsCast());
596607

597-
switch (PackTypes(toType, fromType))
608+
switch (PackTypes(fromType, toType))
598609
{
599-
case PackTypes(TYP_INT, TYP_FLOAT):
610+
case PackTypes(TYP_FLOAT, TYP_INT):
600611
ins = isUnsigned ? INS_i32_trunc_sat_f32_u : INS_i32_trunc_sat_f32_s;
601612
break;
602-
case PackTypes(TYP_INT, TYP_DOUBLE):
613+
case PackTypes(TYP_DOUBLE, TYP_INT):
603614
ins = isUnsigned ? INS_i32_trunc_sat_f64_u : INS_i32_trunc_sat_f64_s;
604615
break;
605-
case PackTypes(TYP_LONG, TYP_FLOAT):
616+
case PackTypes(TYP_FLOAT, TYP_LONG):
606617
ins = isUnsigned ? INS_i64_trunc_sat_f32_u : INS_i64_trunc_sat_f32_s;
607618
break;
608-
case PackTypes(TYP_LONG, TYP_DOUBLE):
619+
case PackTypes(TYP_DOUBLE, TYP_LONG):
609620
ins = isUnsigned ? INS_i64_trunc_sat_f64_u : INS_i64_trunc_sat_f64_s;
610621
break;
611622
default:
@@ -616,18 +627,34 @@ void CodeGen::genFloatToIntCast(GenTree* tree)
616627
genProduceReg(tree);
617628
}
618629

630+
//------------------------------------------------------------------------
631+
// genIntToFloatCast: Generate code for an integer to floating point cast
632+
//
633+
// Arguments:
634+
// tree - The GT_CAST node for the int-to-float cast operation
635+
//
636+
// Notes:
637+
// Handles casts from TYP_INT/TYP_LONG to TYP_FLOAT/TYP_DOUBLE.
638+
// Currently not implemented (NYI_WASM).
639+
//
619640
void CodeGen::genIntToFloatCast(GenTree* tree)
620641
{
621642
NYI_WASM("genIntToFloatCast");
622643
}
623644

645+
//------------------------------------------------------------------------
646+
// genFloatToFloatCast: Generate code for a float to float cast
647+
//
648+
// Arguments:
649+
// tree - The GT_CAST node for the float-to-float cast operation
650+
//
624651
void CodeGen::genFloatToFloatCast(GenTree* tree)
625652
{
626-
var_types toType = genActualType(tree->TypeGet());
627-
var_types fromType = genActualType(tree->AsCast()->CastFromType());
653+
var_types toType = tree->TypeGet();
654+
var_types fromType = tree->AsCast()->CastOp()->TypeGet();
628655
instruction ins = INS_none;
629656

630-
genConsumeRegs(tree->AsCast()->CastOp());
657+
genConsumeOperands(tree->AsCast());
631658

632659
switch (PackTypes(toType, fromType))
633660
{

src/coreclr/jit/emitwasm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include "codegen.h"
1010

1111
// clang-format off
12-
/*static*/ const uint16_t CodeGenInterface::instInfo[] =
12+
/*static*/ const BYTE CodeGenInterface::instInfo[] =
1313
{
1414
#define INST(id, nm, info, fmt, opcode) info,
1515
#include "instrs.h"

0 commit comments

Comments
 (0)