@@ -83,14 +83,11 @@ public override void GetLLInstructions(ref ByteCodeState byteCodeState)
83
83
for ( int i = 0 ; i < byteCodeState . registers . Length ; i ++ )
84
84
byteCodeState . registers [ i ] = null ;
85
85
86
- foreach ( var parameter in function . parameters )
87
- if ( parameter . value . position . type == PositionType . InRegister )
88
- byteCodeState . registers [ parameter . value . position . registerIndex ] = parameter . value ;
86
+ byteCodeState . instructions . Add ( new LLI_StackIncrementImm ( function . minStackSize , 0 ) ) ;
89
87
90
- foreach ( var param in function . parameters )
91
- byteCodeState . instructions . Add ( new LLI_Location_PseudoInstruction ( param . value , function . minStackSize , byteCodeState ) ) ;
88
+ foreach ( var parameter in function . parameters )
89
+ byteCodeState . MarkValueAsPosition ( parameter . value , parameter . value . position , function . minStackSize , false ) ;
92
90
93
- byteCodeState . instructions . Add ( new LLI_StackIncrementImm ( function . minStackSize , 0 ) ) ;
94
91
byteCodeState . instructions . Add ( new LLI_Location_PseudoInstruction ( new CValue ( file , line , new PtrCType ( VoidCType . Instance ) , true ) { description = $ "Instruction pointer of the calling function", hasPosition = true , position = Position . StackOffset ( 0 ) } , function . minStackSize , byteCodeState ) ) ;
95
92
}
96
93
}
@@ -443,11 +440,11 @@ public override void GetLLInstructions(ref ByteCodeState byteCodeState)
443
440
444
441
if ( size <= 8 )
445
442
{
446
- int sourceValueRegister = byteCodeState . CopyValueToAnyRegister ( sourceValue , stackSize ) ;
443
+ int sourceValueRegister = byteCodeState . MoveValueToAnyRegister ( sourceValue , stackSize ) ;
447
444
448
445
using ( var lockedRegister = byteCodeState . LockRegister ( sourceValueRegister ) )
449
446
{
450
- int targetPtrRegister = byteCodeState . CopyValueToAnyRegister ( targetValuePtr , stackSize ) ;
447
+ int targetPtrRegister = byteCodeState . MoveValueToAnyRegister ( targetValuePtr , stackSize ) ;
451
448
452
449
if ( size < 8 )
453
450
byteCodeState . instructions . Add ( new LLI_MovRegisterToPtrInRegister_NBytes ( targetPtrRegister , sourceValueRegister , ( byte ) size ) ) ;
@@ -836,7 +833,7 @@ public override void GetLLInstructions(ref ByteCodeState byteCodeState)
836
833
837
834
if ( ! value . hasPosition )
838
835
{
839
- if ( value . type . isConst || ( value . type is ArrayCType && ( value . type as ArrayCType ) . type . isConst ) || ( value . type is PtrCType && ( value . type as PtrCType ) . pointsTo . isConst ) || ( value . isStatic && Compiler . Assumptions . ByteCodeMutable ) )
836
+ if ( ( value . type is ArrayCType && ( value . type as ArrayCType ) . type . isConst ) || ( value . isStatic && Compiler . Assumptions . ByteCodeMutable ) )
840
837
{
841
838
value . position = Position . CodeBaseOffset ( value , new byte [ value . type . GetSize ( ) ] , file , line ) ;
842
839
byteCodeState . postInstructionDataStorage . Add ( value . position . codeBaseOffset ) ;
@@ -1000,19 +997,9 @@ public override void GetLLInstructions(ref ByteCodeState byteCodeState)
1000
997
else
1001
998
byteCodeState . DumpValue ( source ) ;
1002
999
1003
-
1004
- if ( ! ( source is CNamedValue ) )
1005
- {
1006
- source . hasPosition = false ;
1007
- source . position . type = PositionType . Invalid ;
1008
- }
1009
-
1010
- byteCodeState . MarkValueAsPosition ( target , originalPosition , stackSize , true ) ;
1011
-
1012
1000
source . remainingReferences -- ;
1013
1001
1014
- if ( target . position . type == PositionType . InRegister )
1015
- byteCodeState . registers [ target . position . registerIndex ] = target ;
1002
+ byteCodeState . MarkValueAsPosition ( target , originalPosition , stackSize , true ) ;
1016
1003
}
1017
1004
1018
1005
public override string ToString ( )
@@ -1332,6 +1319,10 @@ public override void GetLLInstructions(ref ByteCodeState byteCodeState)
1332
1319
1333
1320
byteCodeState . instructions . Add ( new LLI_MultiplySignedImm ( rightRegisterIndex , BitConverter . GetBytes ( ( left . type as PtrCType ) . pointsTo . GetSize ( ) ) ) ) ;
1334
1321
}
1322
+ else if ( left is CNamedValue )
1323
+ {
1324
+ rightRegisterIndex = byteCodeState . CopyValueToAnyRegister ( right , stackSize ) ;
1325
+ }
1335
1326
else
1336
1327
{
1337
1328
rightRegisterIndex = byteCodeState . MoveValueToAnyRegister ( right , stackSize ) ;
@@ -1412,30 +1403,75 @@ public override void GetLLInstructions(ref ByteCodeState byteCodeState)
1412
1403
if ( ! right . isInitialized )
1413
1404
Compiler . Error ( $ "Cannot perform operator on uninitialized right value { right } .", file , line ) ;
1414
1405
1406
+ bool isNop = ( right is CConstIntValue && ( ( right . type as BuiltInCType ) . IsUnsigned ( ) && ( right as CConstIntValue ) . uvalue == 1 ) || ( ! ( right . type as BuiltInCType ) . IsUnsigned ( ) && ( right as CConstIntValue ) . ivalue == 1 ) ) || ( right is CConstFloatValue && ( right as CConstFloatValue ) . value == 1.0 ) ;
1407
+
1408
+ if ( isNop )
1409
+ {
1410
+ left . remainingReferences -- ;
1411
+ right . remainingReferences -- ;
1412
+ return ;
1413
+ }
1414
+
1415
+ bool isWrite = ( right is CConstIntValue && ( ( ( right . type as BuiltInCType ) . IsUnsigned ( ) && ( right as CConstIntValue ) . uvalue == 0 ) || ( ! ( right . type as BuiltInCType ) . IsUnsigned ( ) && ( right as CConstIntValue ) . ivalue == 0 ) ) ) || ( right is CConstFloatValue && ( ( right as CConstFloatValue ) . value == 0 || double . IsNaN ( ( right as CConstFloatValue ) . value ) ) ) ;
1416
+
1415
1417
bool leftIsMutableValue = ! ( left is CNamedValue ) ;
1416
- int leftRegisterIndex = leftIsMutableValue || toSelf ? byteCodeState . MoveValueToAnyRegister ( left , stackSize ) : byteCodeState . CopyValueToAnyRegister ( left , stackSize ) ;
1418
+ int leftRegisterIndex = 0 ;
1417
1419
1418
- using ( var registerLock = byteCodeState . LockRegister ( leftRegisterIndex ) )
1420
+ if ( isWrite )
1419
1421
{
1420
- if ( ! toSelf && ( left is CNamedValue || left is CGlobalValueReference ) )
1421
- {
1422
- if ( left is CNamedValue )
1423
- byteCodeState . MoveValueToHome ( left as CNamedValue , stackSize ) ;
1424
- else if ( left is CGlobalValueReference )
1425
- throw new NotImplementedException ( ) ;
1426
- }
1422
+ if ( ( leftIsMutableValue || toSelf ) && left . position . type == PositionType . InRegister )
1423
+ leftRegisterIndex = left . position . registerIndex ;
1424
+ else
1425
+ leftRegisterIndex = ( left . type as BuiltInCType ) . IsFloat ( ) ? byteCodeState . GetFreeFloatRegister ( stackSize ) : byteCodeState . GetFreeIntegerRegister ( stackSize ) ;
1426
+ }
1427
+ else
1428
+ {
1429
+ leftRegisterIndex = leftIsMutableValue || toSelf ? byteCodeState . MoveValueToAnyRegister ( left , stackSize ) : byteCodeState . CopyValueToAnyRegister ( left , stackSize ) ;
1430
+ }
1427
1431
1432
+ using ( var registerLock = byteCodeState . LockRegister ( leftRegisterIndex ) )
1433
+ {
1428
1434
// lvalue can't be imm if rvalue is const, values would've been swapped by the constructor.
1429
1435
if ( right is CConstIntValue )
1430
1436
{
1431
1437
if ( ( left . type is BuiltInCType && ! ( left . type as BuiltInCType ) . IsUnsigned ( ) ) || ( right . type is BuiltInCType && ! ( right . type as BuiltInCType ) . IsUnsigned ( ) ) )
1432
- byteCodeState . instructions . Add ( new LLI_MultiplySignedImm ( leftRegisterIndex , BitConverter . GetBytes ( ( right as CConstIntValue ) . uvalue ) ) ) ;
1438
+ {
1439
+ var rimm = right as CConstIntValue ;
1440
+
1441
+ if ( rimm . ivalue == 0 )
1442
+ byteCodeState . instructions . Add ( new LLI_MovImmToRegister ( leftRegisterIndex , new byte [ 8 ] ) ) ;
1443
+ else if ( rimm . ivalue == 1 )
1444
+ { }
1445
+ else
1446
+ byteCodeState . instructions . Add ( new LLI_MultiplySignedImm ( leftRegisterIndex , BitConverter . GetBytes ( rimm . uvalue ) ) ) ;
1447
+ }
1433
1448
else
1434
- byteCodeState . instructions . Add ( new LLI_MultiplyUnsignedImm ( leftRegisterIndex , BitConverter . GetBytes ( ( right as CConstIntValue ) . uvalue ) ) ) ;
1449
+ {
1450
+ var rimm = right as CConstIntValue ;
1451
+
1452
+ if ( rimm . uvalue == 0 )
1453
+ byteCodeState . instructions . Add ( new LLI_MovImmToRegister ( leftRegisterIndex , new byte [ 8 ] ) ) ;
1454
+ else if ( rimm . uvalue == 1 )
1455
+ { }
1456
+ else
1457
+ byteCodeState . instructions . Add ( new LLI_MultiplyUnsignedImm ( leftRegisterIndex , BitConverter . GetBytes ( rimm . uvalue ) ) ) ;
1458
+ }
1435
1459
}
1436
1460
else if ( right is CConstFloatValue )
1437
1461
{
1438
- byteCodeState . instructions . Add ( new LLI_MultiplySignedImm ( leftRegisterIndex , BitConverter . GetBytes ( ( right as CConstFloatValue ) . value ) ) ) ;
1462
+ var rimm = right as CConstFloatValue ;
1463
+
1464
+ if ( rimm . value == 0 )
1465
+ byteCodeState . instructions . Add ( new LLI_MovImmToRegister ( leftRegisterIndex , new byte [ 8 ] ) ) ;
1466
+ else if ( double . IsNaN ( rimm . value ) )
1467
+ {
1468
+ Compiler . Warn ( $ "Multiplying { left } with { right } , which is NaN.", file , line ) ;
1469
+ byteCodeState . instructions . Add ( new LLI_MovImmToRegister ( leftRegisterIndex , BitConverter . GetBytes ( rimm . value ) ) ) ;
1470
+ }
1471
+ else if ( rimm . value == 1.0 )
1472
+ { }
1473
+ else
1474
+ byteCodeState . instructions . Add ( new LLI_MultiplySignedImm ( leftRegisterIndex , BitConverter . GetBytes ( ( right as CConstFloatValue ) . value ) ) ) ;
1439
1475
}
1440
1476
else
1441
1477
{
@@ -1503,9 +1539,18 @@ public override void GetLLInstructions(ref ByteCodeState byteCodeState)
1503
1539
if ( ! left . isInitialized )
1504
1540
Compiler . Error ( $ "Cannot perform operator on uninitialized left value { left } .", file , line ) ;
1505
1541
1506
- if ( ! left . isInitialized )
1542
+ if ( ! right . isInitialized )
1507
1543
Compiler . Error ( $ "Cannot perform operator on uninitialized right value { right } .", file , line ) ;
1508
1544
1545
+ bool isNop = ( right is CConstIntValue && ( ( right . type as BuiltInCType ) . IsUnsigned ( ) && ( right as CConstIntValue ) . uvalue == 1 ) || ( ! ( right . type as BuiltInCType ) . IsUnsigned ( ) && ( right as CConstIntValue ) . ivalue == 1 ) ) || ( right is CConstFloatValue && ( right as CConstFloatValue ) . value == 1.0 ) ;
1546
+
1547
+ if ( isNop )
1548
+ {
1549
+ left . remainingReferences -- ;
1550
+ right . remainingReferences -- ;
1551
+ return ;
1552
+ }
1553
+
1509
1554
bool leftIsMutableValue = ! ( left is CNamedValue ) ;
1510
1555
int leftRegisterIndex = leftIsMutableValue || toSelf ? byteCodeState . MoveValueToAnyRegister ( left , stackSize ) : byteCodeState . CopyValueToAnyRegister ( left , stackSize ) ;
1511
1556
@@ -1521,14 +1566,28 @@ public override void GetLLInstructions(ref ByteCodeState byteCodeState)
1521
1566
1522
1567
if ( right is CConstIntValue )
1523
1568
{
1569
+ var rimm = right as CConstIntValue ;
1570
+
1524
1571
if ( ( left . type is BuiltInCType && ! ( left . type as BuiltInCType ) . IsUnsigned ( ) ) || ( right . type is BuiltInCType && ! ( right . type as BuiltInCType ) . IsUnsigned ( ) ) )
1525
- byteCodeState . instructions . Add ( new LLI_DivideSignedImm ( leftRegisterIndex , BitConverter . GetBytes ( ( right as CConstIntValue ) . uvalue ) ) ) ;
1572
+ {
1573
+ if ( rimm . ivalue == 0 )
1574
+ Compiler . Error ( $ "Attempting to divide { left } by zero ({ right } ).", file , line ) ;
1575
+
1576
+ byteCodeState . instructions . Add ( new LLI_DivideSignedImm ( leftRegisterIndex , BitConverter . GetBytes ( rimm . ivalue ) ) ) ;
1577
+ }
1526
1578
else
1527
- byteCodeState . instructions . Add ( new LLI_DivideUnsignedImm ( leftRegisterIndex , BitConverter . GetBytes ( ( right as CConstIntValue ) . uvalue ) ) ) ;
1579
+ {
1580
+ if ( rimm . uvalue == 0 )
1581
+ Compiler . Error ( $ "Attempting to divide { left } by zero ({ right } ).", file , line ) ;
1582
+
1583
+ byteCodeState . instructions . Add ( new LLI_DivideUnsignedImm ( leftRegisterIndex , BitConverter . GetBytes ( rimm . uvalue ) ) ) ;
1584
+ }
1528
1585
}
1529
1586
else if ( right is CConstFloatValue )
1530
1587
{
1531
- byteCodeState . instructions . Add ( new LLI_DivideSignedImm ( leftRegisterIndex , BitConverter . GetBytes ( ( right as CConstFloatValue ) . value ) ) ) ;
1588
+ // Multiplying should be faster than dividing.
1589
+ //byteCodeState.instructions.Add(new LLI_DivideSignedImm(leftRegisterIndex, BitConverter.GetBytes((right as CConstFloatValue).value)));
1590
+ byteCodeState . instructions . Add ( new LLI_MultiplySignedImm ( leftRegisterIndex , BitConverter . GetBytes ( 1.0 / ( right as CConstFloatValue ) . value ) ) ) ;
1532
1591
}
1533
1592
else
1534
1593
{
0 commit comments