Added support for bitwise operators.
Added support for bitwise operators.
1.1 --- a/jitcraft/BytecodeCompiler.cpp Wed Jun 27 22:02:40 2012 -0700
1.2 +++ b/jitcraft/BytecodeCompiler.cpp Thu Jun 28 00:26:55 2012 -0700
1.3 @@ -76,6 +76,18 @@
1.4 return OP_MUL;
1.5 case TOK_SLASH:
1.6 return OP_DIV;
1.7 + case TOK_SHR:
1.8 + return OP_SHR;
1.9 + case TOK_USHR:
1.10 + return OP_USHR;
1.11 + case TOK_SHL:
1.12 + return OP_SHL;
1.13 + case TOK_BITAND:
1.14 + return OP_BITAND;
1.15 + case TOK_BITOR:
1.16 + return OP_BITOR;
1.17 + case TOK_BITXOR:
1.18 + return OP_BITXOR;
1.19 }
1.20 assert(false);
1.21 return OP_NOP;
2.1 --- a/jitcraft/Interpreter.cpp Wed Jun 27 22:02:40 2012 -0700
2.2 +++ b/jitcraft/Interpreter.cpp Thu Jun 28 00:26:55 2012 -0700
2.3 @@ -366,6 +366,60 @@
2.4 break;
2.5 }
2.6
2.7 +case OP_SHL:
2.8 +{
2.9 + int right = POP_I32(top);
2.10 + int left = POP_I32(top);
2.11 + int result = left << right;
2.12 + PUSH_I32(top, result);
2.13 + break;
2.14 +}
2.15 +
2.16 +case OP_SHR:
2.17 +{
2.18 + int right = POP_I32(top);
2.19 + int left = POP_I32(top);
2.20 + int result = left >> right;
2.21 + PUSH_I32(top, result);
2.22 + break;
2.23 +}
2.24 +
2.25 +case OP_USHR:
2.26 +{
2.27 + int right = POP_I32(top);
2.28 + int left = POP_I32(top);
2.29 + int result = unsigned(left) >> unsigned(right);
2.30 + PUSH_I32(top, result);
2.31 + break;
2.32 +}
2.33 +
2.34 +case OP_BITAND:
2.35 +{
2.36 + int right = POP_I32(top);
2.37 + int left = POP_I32(top);
2.38 + int result = left & right;
2.39 + PUSH_I32(top, result);
2.40 + break;
2.41 +}
2.42 +
2.43 +case OP_BITOR:
2.44 +{
2.45 + int right = POP_I32(top);
2.46 + int left = POP_I32(top);
2.47 + int result = left | right;
2.48 + PUSH_I32(top, result);
2.49 + break;
2.50 +}
2.51 +
2.52 +case OP_BITXOR:
2.53 +{
2.54 + int right = POP_I32(top);
2.55 + int left = POP_I32(top);
2.56 + int result = left ^ right;
2.57 + PUSH_I32(top, result);
2.58 + break;
2.59 +}
2.60 +
2.61 case OP_POP:
2.62 top.sp--;
2.63 break;
3.1 --- a/jitcraft/Opcodes.cpp Wed Jun 27 22:02:40 2012 -0700
3.2 +++ b/jitcraft/Opcodes.cpp Thu Jun 28 00:26:55 2012 -0700
3.3 @@ -67,6 +67,12 @@
3.4 case OP_SETARRAY_F:
3.5 case OP_GETARRAY_P:
3.6 case OP_BOUNDS_STA:
3.7 + case OP_SHL:
3.8 + case OP_SHR:
3.9 + case OP_USHR:
3.10 + case OP_BITAND:
3.11 + case OP_BITOR:
3.12 + case OP_BITXOR:
3.13 break;
3.14
3.15 case OP_STOP:
4.1 --- a/jitcraft/Opcodes.tbl Wed Jun 27 22:02:40 2012 -0700
4.2 +++ b/jitcraft/Opcodes.tbl Thu Jun 28 00:26:55 2012 -0700
4.3 @@ -89,8 +89,8 @@
4.4 //
4.5 OPDEF(OP_GETARRAY_I, 23, "getarray.i", 1, 2, 1)
4.6 OPDEF(OP_SETARRAY_I, 24, "setarray.i", 1, 3, 1)
4.7 -OPDEF(OP_GETARRAY_F, 25, "getarray.i", 1, 2, 1)
4.8 -OPDEF(OP_SETARRAY_F, 26, "setarray.i", 1, 3, 1)
4.9 +OPDEF(OP_GETARRAY_F, 25, "getarray.f", 1, 2, 1)
4.10 +OPDEF(OP_SETARRAY_F, 26, "setarray.f", 1, 3, 1)
4.11 OPDEF(OP_GETARRAY_P, 27, "getarray.p", 1, 2, 1)
4.12
4.13 // Allocate an array of N dimensions into unsafe memory. Each dimension size
4.14 @@ -134,3 +134,10 @@
4.15 OPDEF(OP_MUL_F, 35, "mul.f", 1, 2, 1)
4.16 OPDEF(OP_DIV_F, 36, "div.f", 1, 2, 1)
4.17
4.18 +// Bitwise operators.
4.19 +OPDEF(OP_SHL, 37, "shl", 1, 2, 1)
4.20 +OPDEF(OP_SHR, 38, "shr", 1, 2, 1)
4.21 +OPDEF(OP_USHR, 39, "ushr", 1, 2, 1)
4.22 +OPDEF(OP_BITAND, 40, "bitand", 1, 2, 1)
4.23 +OPDEF(OP_BITOR, 41, "bitor", 1, 2, 1)
4.24 +OPDEF(OP_BITXOR, 42, "bitxor", 1, 2, 1)
5.1 --- a/jitcraft/Parser.cpp Wed Jun 27 22:02:40 2012 -0700
5.2 +++ b/jitcraft/Parser.cpp Thu Jun 28 00:26:55 2012 -0700
5.3 @@ -251,7 +251,7 @@
5.4 {
5.5 Expression *left = addition();
5.6 while (left) {
5.7 - if (!match(TOK_SHL))
5.8 + if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
5.9 break;
5.10 TokenKind kind = scanner_.last();
5.11 Expression *right = addition();
5.12 @@ -263,9 +263,54 @@
5.13 }
5.14
5.15 Expression *
5.16 +Parser::bitand()
5.17 +{
5.18 + Expression *left = shift();
5.19 + while (left) {
5.20 + if (!match(TOK_BITAND))
5.21 + break;
5.22 + Expression *right = shift();
5.23 + if (!right)
5.24 + return NULL;
5.25 + left = new (pool_) BinaryExpression(TOK_BITAND, left, right);
5.26 + }
5.27 + return left;
5.28 +}
5.29 +
5.30 +Expression *
5.31 +Parser::bitxor()
5.32 +{
5.33 + Expression *left = bitand();
5.34 + while (left) {
5.35 + if (!match(TOK_BITXOR))
5.36 + break;
5.37 + Expression *right = shift();
5.38 + if (!right)
5.39 + return NULL;
5.40 + left = new (pool_) BinaryExpression(TOK_BITXOR, left, right);
5.41 + }
5.42 + return left;
5.43 +}
5.44 +
5.45 +Expression *
5.46 +Parser::bitor()
5.47 +{
5.48 + Expression *left = bitxor();
5.49 + while (left) {
5.50 + if (!match(TOK_BITOR))
5.51 + break;
5.52 + Expression *right = shift();
5.53 + if (!right)
5.54 + return NULL;
5.55 + left = new (pool_) BinaryExpression(TOK_BITOR, left, right);
5.56 + }
5.57 + return left;
5.58 +}
5.59 +
5.60 +Expression *
5.61 Parser::relational()
5.62 {
5.63 - Expression *left = shift();
5.64 + Expression *left = bitor();
5.65 while (left) {
5.66 TokenKind kind = scanner_.peek();
5.67 if (kind < TOK_LT || kind > TOK_GE)
6.1 --- a/jitcraft/Parser.h Wed Jun 27 22:02:40 2012 -0700
6.2 +++ b/jitcraft/Parser.h Thu Jun 28 00:26:55 2012 -0700
6.3 @@ -55,8 +55,11 @@
6.4 Expression *primary();
6.5 Expression *unary();
6.6 Expression *multiplication();
6.7 + Expression *addition();
6.8 Expression *shift();
6.9 - Expression *addition();
6.10 + Expression *bitand();
6.11 + Expression *bitxor();
6.12 + Expression *bitor();
6.13 Expression *relational();
6.14 Expression *equals();
6.15 Expression *expression();
7.1 --- a/jitcraft/Scanner.cpp Wed Jun 27 22:02:40 2012 -0700
7.2 +++ b/jitcraft/Scanner.cpp Thu Jun 28 00:26:55 2012 -0700
7.3 @@ -274,6 +274,15 @@
7.4 putChar(c);
7.5 return TOK_PLUS;
7.6
7.7 + case '&':
7.8 + return TOK_BITAND;
7.9 +
7.10 + case '|':
7.11 + return TOK_BITOR;
7.12 +
7.13 + case '^':
7.14 + return TOK_BITXOR;
7.15 +
7.16 case '-': return TOK_MINUS;
7.17 case ',': return TOK_COMMA;
7.18 case '\0': return TOK_EOF;
7.19 @@ -302,6 +311,12 @@
7.20 c = getChar();
7.21 if (c == '=')
7.22 return TOK_GE;
7.23 + if (c == '>') {
7.24 + c = getChar();
7.25 + if (c == '>')
7.26 + return TOK_USHR;
7.27 + return TOK_SHR;
7.28 + }
7.29 putChar(c);
7.30 return TOK_GT;
7.31
8.1 --- a/jitcraft/SemanticAnalysis.cpp Wed Jun 27 22:02:40 2012 -0700
8.2 +++ b/jitcraft/SemanticAnalysis.cpp Thu Jun 28 00:26:55 2012 -0700
8.3 @@ -183,12 +183,12 @@
8.4 node->setType(left->isFloat() ? left : right);
8.5 return;
8.6 }
8.7 + }
8.8
8.9 - // Otherwise, both sides must be integer.
8.10 - assert(left->isInt() && right->isInt());
8.11 - node->setType(left);
8.12 - return;
8.13 - }
8.14 + // For now, assert everything else is integer and untagged.
8.15 + assert(left->isInt() && right->isInt());
8.16 + assert(!left->tag() && !right->tag());
8.17 + node->setType(left);
8.18 }
8.19
8.20 void
8.21 @@ -257,6 +257,9 @@
8.22
8.23 type = Type::NewUnsafeArray(type, size);
8.24 }
8.25 + } else {
8.26 + Type *right = visitForLoad(node->initialization());
8.27 + assert(TypeCheck(type, right));
8.28 }
8.29
8.30 node->variable()->setType(type);
9.1 --- a/jitcraft/Token.h Wed Jun 27 22:02:40 2012 -0700
9.2 +++ b/jitcraft/Token.h Thu Jun 28 00:26:55 2012 -0700
9.3 @@ -36,6 +36,11 @@
9.4 _(MINUS, "-") \
9.5 _(STAR, "*") \
9.6 _(SLASH, "/") \
9.7 + _(BITAND, "&") \
9.8 + _(BITOR, "|") \
9.9 + _(BITXOR, "^") \
9.10 + _(SHR, ">>") \
9.11 + _(USHR, ">>>") \
9.12 _(SHL, "<<") \
9.13 _(ASSIGN, "=") \
9.14 _(SEMICOLON, ";") \
10.1 --- a/jitcraft/Types.h Wed Jun 27 22:02:40 2012 -0700
10.2 +++ b/jitcraft/Types.h Thu Jun 28 00:26:55 2012 -0700
10.3 @@ -68,6 +68,10 @@
10.4 assert(isArray());
10.5 return levels_;
10.6 }
10.7 + Name *tag() const {
10.8 + assert(isPrimitive());
10.9 + return tag_;
10.10 + }
10.11 Type *innermost() const {
10.12 assert(isArray());
10.13 Type *temp = contained();
11.1 --- a/jitcraft/main.cpp Wed Jun 27 22:02:40 2012 -0700
11.2 +++ b/jitcraft/main.cpp Thu Jun 28 00:26:55 2012 -0700
11.3 @@ -96,7 +96,7 @@
11.4 if (!Interpret(frame, &result))
11.5 return false;
11.6
11.7 - printf("Result: %f\n", result.f);
11.8 + printf("Result: %d\n", result.i32);
11.9
11.10 return true;
11.11 }
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/tests/prototype/bitops.sp Thu Jun 28 00:26:55 2012 -0700
12.3 @@ -0,0 +1,14 @@
12.4 +main()
12.5 +{
12.6 + new result = 5192342;
12.7 + for (new i = 0; i < 100000; i = i + 1) {
12.8 + result = result | i;
12.9 + result = result & 9129345;
12.10 + result = result ^ (i * 73);
12.11 +
12.12 + new bit = result & 1;
12.13 + result = (result >>> 1) | (bit << 31);
12.14 + result = result | (i >> 6);
12.15 + }
12.16 + return result;
12.17 +}