Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement bitwise operators #2

Open
wants to merge 3 commits into
base: remake
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions IL2X.Core/ASMHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,16 @@ public enum ASMCode

// arithmatic
Add,
Sub,
Sub,
Mul,
Div,
BitwiseAnd,
BitwiseOr,
BitwiseXor,
BitwiseNot,
ShiftLeft,
ShiftRight,
ShiftRightUnsigned,

// writes
WriteLocal,
Expand All @@ -48,7 +55,7 @@ public enum ASMCode
CmpLess_1_0,

// invoke
CallMethod
CallMethod,
}

public class ASMObject
Expand Down
44 changes: 44 additions & 0 deletions IL2X.Core/Emitters/Emmiter_C.cs
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,50 @@ private string GetOperationValue(ASMObject op)
return $"{GetOperationValue(arithmaticOp.value1)} + {GetOperationValue(arithmaticOp.value2)}";
}

case ASMCode.BitwiseAnd:
{
var arithmaticOp = (ASMArithmatic)op;
return $"{GetOperationValue(arithmaticOp.value1)} & {GetOperationValue(arithmaticOp.value2)}";
}

case ASMCode.BitwiseOr:
{
var arithmaticOp = (ASMArithmatic)op;
return $"{GetOperationValue(arithmaticOp.value1)} | {GetOperationValue(arithmaticOp.value2)}";
}

case ASMCode.BitwiseXor:
{
var arithmaticOp = (ASMArithmatic)op;
return $"{GetOperationValue(arithmaticOp.value1)} ^ {GetOperationValue(arithmaticOp.value2)}";
}

case ASMCode.BitwiseNot:
{
var arithmaticOp = (ASMArithmatic)op;
return $"~{GetOperationValue(arithmaticOp.value1)}";
}

case ASMCode.ShiftLeft:
{
var arithmaticOp = (ASMArithmatic)op;
return $"{GetOperationValue(arithmaticOp.value1)} << {GetOperationValue(arithmaticOp.value2)}";
}

//NOTE: this is an arithmetic shift right
case ASMCode.ShiftRight:
{
var arithmaticOp = (ASMArithmatic)op;
return $"{GetOperationValue(arithmaticOp.value1)} >> {GetOperationValue(arithmaticOp.value2)}";
}

//NOTE: this is a logical shift right
case ASMCode.ShiftRightUnsigned:
{
var arithmaticOp = (ASMArithmatic)op;
return $"{GetOperationValue(arithmaticOp.value1)} >> {GetOperationValue(arithmaticOp.value2)}";
}

case ASMCode.Sub:
{
var arithmaticOp = (ASMArithmatic)op;
Expand Down
96 changes: 96 additions & 0 deletions IL2X.Core/Jit/MethodJit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,51 @@ private void InterpretInstructionFlow(Instruction op)
break;
}

case Code.And:
{
var p2 = StackPop();
var p1 = StackPop();
var evalVarType = GetArithmaticResultType(p1.obj, p2.obj);
var evalVar = GetEvalStackVar(evalVarType);
AddASMOp(new ASMArithmatic(ASMCode.BitwiseAnd, OperandToASMOperand(p1.obj), OperandToASMOperand(p2.obj), evalVar));
StackPush(op, evalVar);
break;
}

case Code.Not:
{
var p1 = StackPop();

var evalVar = GetEvalStackVar(GetArithmaticResultType(p1.obj));

AddASMOp(new ASMArithmatic(ASMCode.BitwiseNot, OperandToASMOperand(p1.obj), null, evalVar));
StackPush(op, evalVar);
break;

}

case Code.Or:
{
var p2 = StackPop();
var p1 = StackPop();
var evalVarType = GetArithmaticResultType(p1.obj, p2.obj);
var evalVar = GetEvalStackVar(evalVarType);
AddASMOp(new ASMArithmatic(ASMCode.BitwiseOr, OperandToASMOperand(p1.obj), OperandToASMOperand(p2.obj), evalVar));
StackPush(op, evalVar);
break;
}

case Code.Xor:
{
var p2 = StackPop();
var p1 = StackPop();
var evalVarType = GetArithmaticResultType(p1.obj, p2.obj);
var evalVar = GetEvalStackVar(evalVarType);
AddASMOp(new ASMArithmatic(ASMCode.BitwiseXor, OperandToASMOperand(p1.obj), OperandToASMOperand(p2.obj), evalVar));
StackPush(op, evalVar);
break;
}

case Code.Sub:
{
var p2 = StackPop();
Expand Down Expand Up @@ -171,6 +216,39 @@ private void InterpretInstructionFlow(Instruction op)
break;
}

case Code.Shl:
{
var shiftAmount = StackPop();
var value = StackPop();
var evalVarType = GetArithmaticResultType(value.obj);
var evalVar = GetEvalStackVar(evalVarType);
AddASMOp(new ASMArithmatic(ASMCode.ShiftLeft, OperandToASMOperand(value.obj), OperandToASMOperand(shiftAmount.obj), evalVar));
StackPush(op, evalVar);
break;
}

case Code.Shr:
{
var shiftAmount = StackPop();
var value = StackPop();
var evalVarType = GetArithmaticResultType(value.obj);
var evalVar = GetEvalStackVar(evalVarType);
AddASMOp(new ASMArithmatic(ASMCode.ShiftRight, OperandToASMOperand(value.obj), OperandToASMOperand(shiftAmount.obj), evalVar));
StackPush(op, evalVar);
break;
}

case Code.Shr_Un:
{
var shiftAmount = StackPop();
var value = StackPop();
var evalVarType = GetArithmaticResultType(value.obj);
var evalVar = GetEvalStackVar(evalVarType);
AddASMOp(new ASMArithmatic(ASMCode.ShiftRightUnsigned, OperandToASMOperand(value.obj), OperandToASMOperand(shiftAmount.obj), evalVar));
StackPush(op, evalVar);
break;
}

// ===================================
// loads
// ===================================
Expand Down Expand Up @@ -673,6 +751,23 @@ private void BranchOnCondition(Instruction op, Instruction jmpToOp, ASMCode bran
}
}

private TypeReference GetArithmaticResultType(object value)
{
if (value is VariableReference value_Var) return value_Var.VariableType;
if (value is ParameterReference value_Param) return value_Param.ParameterType;
if (value is Int16) return GetTypeSystem().Int16;
if (value is Int32) return GetTypeSystem().Int32;
if (value is Int64) return GetTypeSystem().Int64;
if (value is UInt16) return GetTypeSystem().UInt16;
if (value is UInt32) return GetTypeSystem().UInt32;
if (value is UInt64) return GetTypeSystem().UInt64;
if (value is Single) return GetTypeSystem().Single;
if (value is Double) return GetTypeSystem().Double;
if (value is ASMSizeOf) return GetTypeSystem().Int32;
if (value is ASMEvalStackLocal local) return local.type;
throw new NotImplementedException("Unsupported arithmatic object: " + value.GetType().ToString());
}

private TypeReference GetArithmaticResultType(object value1, object value2)
{
TypeReference GetType(object value)
Expand All @@ -688,6 +783,7 @@ TypeReference GetType(object value)
if (value is Single) return GetTypeSystem().Single;
if (value is Double) return GetTypeSystem().Double;
if (value is ASMSizeOf) return GetTypeSystem().Int32;
if (value is ASMEvalStackLocal local) return local.type;
throw new NotImplementedException("Unsupported arithmatic object: " + value.GetType().ToString());
}

Expand Down
2 changes: 2 additions & 0 deletions RayTraceBenchmark/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public class Program
static void Main()
{
int a = Foo(123);
int b = 24;
int c = (a ^ b & a | ~b >> 3) << 1;
EXIT:;
if (a == 124) a = -200;
for (int i = 0; i != 2; ++i)
Expand Down