Commit 753ae0ab authored by Brendan Gregg's avatar Brendan Gregg Committed by GitHub

Merge pull request #88 from iovisor/parser

support shift left and right
parents e52025aa 22f2384a
...@@ -87,6 +87,8 @@ std::string opstr(Binop &binop) ...@@ -87,6 +87,8 @@ std::string opstr(Binop &binop)
case bpftrace::Parser::token::GT: return ">"; case bpftrace::Parser::token::GT: return ">";
case bpftrace::Parser::token::LAND: return "&&"; case bpftrace::Parser::token::LAND: return "&&";
case bpftrace::Parser::token::LOR: return "||"; case bpftrace::Parser::token::LOR: return "||";
case bpftrace::Parser::token::LEFT: return "<<";
case bpftrace::Parser::token::RIGHT: return ">>";
case bpftrace::Parser::token::PLUS: return "+"; case bpftrace::Parser::token::PLUS: return "+";
case bpftrace::Parser::token::MINUS: return "-"; case bpftrace::Parser::token::MINUS: return "-";
case bpftrace::Parser::token::MUL: return "*"; case bpftrace::Parser::token::MUL: return "*";
......
...@@ -596,6 +596,8 @@ void CodegenLLVM::visit(Binop &binop) ...@@ -596,6 +596,8 @@ void CodegenLLVM::visit(Binop &binop)
case bpftrace::Parser::token::GE: expr_ = b_.CreateICmpSGE(lhs, rhs); break; case bpftrace::Parser::token::GE: expr_ = b_.CreateICmpSGE(lhs, rhs); break;
case bpftrace::Parser::token::LT: expr_ = b_.CreateICmpSLT(lhs, rhs); break; case bpftrace::Parser::token::LT: expr_ = b_.CreateICmpSLT(lhs, rhs); break;
case bpftrace::Parser::token::GT: expr_ = b_.CreateICmpSGT(lhs, rhs); break; case bpftrace::Parser::token::GT: expr_ = b_.CreateICmpSGT(lhs, rhs); break;
case bpftrace::Parser::token::LEFT: expr_ = b_.CreateShl (lhs, rhs); break;
case bpftrace::Parser::token::RIGHT: expr_ = b_.CreateLShr (lhs, rhs); break;
case bpftrace::Parser::token::PLUS: expr_ = b_.CreateAdd (lhs, rhs); break; case bpftrace::Parser::token::PLUS: expr_ = b_.CreateAdd (lhs, rhs); break;
case bpftrace::Parser::token::MINUS: expr_ = b_.CreateSub (lhs, rhs); break; case bpftrace::Parser::token::MINUS: expr_ = b_.CreateSub (lhs, rhs); break;
case bpftrace::Parser::token::MUL: expr_ = b_.CreateMul (lhs, rhs); break; case bpftrace::Parser::token::MUL: expr_ = b_.CreateMul (lhs, rhs); break;
......
...@@ -67,6 +67,8 @@ pid|tid|uid|gid|nsecs|cpu|comm|stack|ustack|arg[0-9]|retval|func|name|curtask|ra ...@@ -67,6 +67,8 @@ pid|tid|uid|gid|nsecs|cpu|comm|stack|ustack|arg[0-9]|retval|func|name|curtask|ra
"!=" { return Parser::make_NE(loc); } "!=" { return Parser::make_NE(loc); }
"<=" { return Parser::make_LE(loc); } "<=" { return Parser::make_LE(loc); }
">=" { return Parser::make_GE(loc); } ">=" { return Parser::make_GE(loc); }
"<<" { return Parser::make_LEFT(loc); }
">>" { return Parser::make_RIGHT(loc); }
"<" { return Parser::make_LT(loc); } "<" { return Parser::make_LT(loc); }
">" { return Parser::make_GT(loc); } ">" { return Parser::make_GT(loc); }
"&&" { return Parser::make_LAND(loc); } "&&" { return Parser::make_LAND(loc); }
......
...@@ -52,6 +52,8 @@ void yyerror(bpftrace::Driver &driver, const char *s); ...@@ -52,6 +52,8 @@ void yyerror(bpftrace::Driver &driver, const char *s);
NE "!=" NE "!="
LE "<=" LE "<="
GE ">=" GE ">="
LEFT "<<"
RIGHT ">>"
LT "<" LT "<"
GT ">" GT ">"
LAND "&&" LAND "&&"
...@@ -106,6 +108,7 @@ void yyerror(bpftrace::Driver &driver, const char *s); ...@@ -106,6 +108,7 @@ void yyerror(bpftrace::Driver &driver, const char *s);
%left BAND %left BAND
%left EQ NE %left EQ NE
%left LE GE LT GT %left LE GE LT GT
%left LEFT RIGHT
%left PLUS MINUS %left PLUS MINUS
%left MUL DIV MOD %left MUL DIV MOD
%right LNOT BNOT DEREF CAST %right LNOT BNOT DEREF CAST
...@@ -183,6 +186,8 @@ expr : INT { $$ = new ast::Integer($1); } ...@@ -183,6 +186,8 @@ expr : INT { $$ = new ast::Integer($1); }
| expr GT expr { $$ = new ast::Binop($1, token::GT, $3); } | expr GT expr { $$ = new ast::Binop($1, token::GT, $3); }
| expr LAND expr { $$ = new ast::Binop($1, token::LAND, $3); } | expr LAND expr { $$ = new ast::Binop($1, token::LAND, $3); }
| expr LOR expr { $$ = new ast::Binop($1, token::LOR, $3); } | expr LOR expr { $$ = new ast::Binop($1, token::LOR, $3); }
| expr LEFT expr { $$ = new ast::Binop($1, token::LEFT, $3); }
| expr RIGHT expr { $$ = new ast::Binop($1, token::RIGHT, $3); }
| expr PLUS expr { $$ = new ast::Binop($1, token::PLUS, $3); } | expr PLUS expr { $$ = new ast::Binop($1, token::PLUS, $3); }
| expr MINUS expr { $$ = new ast::Binop($1, token::MINUS, $3); } | expr MINUS expr { $$ = new ast::Binop($1, token::MINUS, $3); }
| expr MUL expr { $$ = new ast::Binop($1, token::MUL, $3); } | expr MUL expr { $$ = new ast::Binop($1, token::MUL, $3); }
......
...@@ -2249,6 +2249,76 @@ attributes #1 = { argmemonly nounwind } ...@@ -2249,6 +2249,76 @@ attributes #1 = { argmemonly nounwind }
)EXPECTED"); )EXPECTED");
} }
TEST(codegen, bitshift_left)
{
test("kprobe:f { @x = 1 << 10; }",
R"EXPECTED(; Function Attrs: nounwind
declare i64 @llvm.bpf.pseudo(i64, i64) #0
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
define i64 @"kprobe:f"(i8* nocapture readnone) local_unnamed_addr section "s_kprobe:f" {
entry:
%"@x_val" = alloca i64, align 8
%"@x_key" = alloca i64, align 8
%1 = bitcast i64* %"@x_key" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1)
store i64 0, i64* %"@x_key", align 8
%2 = bitcast i64* %"@x_val" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %2)
store i64 1024, i64* %"@x_val", align 8
%pseudo = tail call i64 @llvm.bpf.pseudo(i64 1, i64 1)
%update_elem = call i64 inttoptr (i64 2 to i64 (i8*, i8*, i8*, i64)*)(i64 %pseudo, i64* nonnull %"@x_key", i64* nonnull %"@x_val", i64 0)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %1)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %2)
ret i64 0
}
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
attributes #0 = { nounwind }
attributes #1 = { argmemonly nounwind }
)EXPECTED");
}
TEST(codegen, bitshift_right)
{
test("kprobe:f { @x = 1024 >> 9; }",
R"EXPECTED(; Function Attrs: nounwind
declare i64 @llvm.bpf.pseudo(i64, i64) #0
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
define i64 @"kprobe:f"(i8* nocapture readnone) local_unnamed_addr section "s_kprobe:f" {
entry:
%"@x_val" = alloca i64, align 8
%"@x_key" = alloca i64, align 8
%1 = bitcast i64* %"@x_key" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1)
store i64 0, i64* %"@x_key", align 8
%2 = bitcast i64* %"@x_val" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %2)
store i64 2, i64* %"@x_val", align 8
%pseudo = tail call i64 @llvm.bpf.pseudo(i64 1, i64 1)
%update_elem = call i64 inttoptr (i64 2 to i64 (i8*, i8*, i8*, i64)*)(i64 %pseudo, i64* nonnull %"@x_key", i64* nonnull %"@x_val", i64 0)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %1)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %2)
ret i64 0
}
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
attributes #0 = { nounwind }
attributes #1 = { argmemonly nounwind }
)EXPECTED");
}
TEST(codegen, ternary_int) TEST(codegen, ternary_int)
{ {
test("kprobe:f { @x = pid < 10000 ? 1 : 2; }", test("kprobe:f { @x = pid < 10000 ? 1 : 2; }",
......
...@@ -239,6 +239,39 @@ TEST(Parser, expressions) ...@@ -239,6 +239,39 @@ TEST(Parser, expressions)
" int: 1\n"); " int: 1\n");
} }
TEST(Parser, bit_shifting)
{
test("kprobe:do_nanosleep { @x = 1 << 10 }",
"Program\n"
" kprobe:do_nanosleep\n"
" =\n"
" map: @x\n"
" <<\n"
" int: 1\n"
" int: 10\n");
test("kprobe:do_nanosleep { @x = 1024 >> 9 }",
"Program\n"
" kprobe:do_nanosleep\n"
" =\n"
" map: @x\n"
" >>\n"
" int: 1024\n"
" int: 9\n");
test("kprobe:do_nanosleep / 2 < 1 >> 8 / { $x = 1 }",
"Program\n"
" kprobe:do_nanosleep\n"
" pred\n"
" <\n"
" int: 2\n"
" >>\n"
" int: 1\n"
" int: 8\n"
" =\n"
" variable: $x\n"
" int: 1\n");
}
TEST(Parser, ternary_int) TEST(Parser, ternary_int)
{ {
test("kprobe:sys_open { @x = pid < 10000 ? 1 : 2 }", test("kprobe:sys_open { @x = pid < 10000 ? 1 : 2 }",
......
...@@ -34,8 +34,8 @@ interval:s:1 ...@@ -34,8 +34,8 @@ interval:s:1
$load15 = *($avenrun + 16); $load15 = *($avenrun + 16);
time("%H:%M:%S "); time("%H:%M:%S ");
printf("load averages: %d.%03d %d.%03d %d.%03d\n", printf("load averages: %d.%03d %d.%03d %d.%03d\n",
($load1 / 2048), (($load1 & 2047) * 1000) / 2048, ($load1 >> 11), (($load1 & ((1 << 11) - 1)) * 1000) >> 11,
($load5 / 2048), (($load5 & 2047) * 1000) / 2048, ($load5 >> 11), (($load5 & ((1 << 11) - 1)) * 1000) >> 11,
($load15 / 2048), (($load15 & 2047) * 1000) / 2048 ($load15 >> 11), (($load15 & ((1 << 11) - 1)) * 1000) >> 11
); );
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment