Skip to content

Commit 7b11022

Browse files
committed
xor
1 parent d05794c commit 7b11022

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

src/vm/jvm/QAST/Compiler.nqp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ my $SWAP := JAST::Instruction.new( :op('swap') );
1818
my $IADD := JAST::Instruction.new( :op('iadd') );
1919
my $LADD := JAST::Instruction.new( :op('ladd') );
2020
my $LSUB := JAST::Instruction.new( :op('lsub') );
21+
my $IAND := JAST::Instruction.new( :op('iand') );
2122
my $I2L := JAST::Instruction.new( :op('i2l') );
2223
my $I2B := JAST::Instruction.new( :op('i2b') );
2324
my $L2I := JAST::Instruction.new( :op('l2i') );
@@ -877,6 +878,98 @@ QAST::OperationsJAST.add_core_op('defor', -> $qastcomp, $op {
877878
)))
878879
});
879880

881+
QAST::OperationsJAST.add_core_op('xor', -> $qastcomp, $op {
882+
my $falselabel := JAST::Label.new(:name('xor_false'));
883+
my $endlabel := JAST::Label.new(:name('xor_end'));
884+
885+
my @childlist;
886+
my $fpast;
887+
for $op.list {
888+
if $_.named eq 'false' {
889+
$fpast := $_;
890+
}
891+
else {
892+
nqp::push(@childlist, $_);
893+
}
894+
}
895+
896+
my $r := $*TA.fresh_o();
897+
my $b := $*TA.fresh_o();
898+
my $i := $*TA.fresh_i();
899+
my $t := $*TA.fresh_i();
900+
my $u := $*TA.fresh_i();
901+
902+
my $il := JAST::InstructionList.new();
903+
my $apast := nqp::shift(@childlist);
904+
my $ares := $qastcomp.as_jast($apast, :want($RT_OBJ));
905+
$il.append($ares.jast);
906+
$*STACK.obtain($il, $ares);
907+
$il.append($DUP);
908+
$il.append(JAST::Instruction.new( :op('astore'), $r ));
909+
$il.append($ALOAD_1);
910+
$il.append(JAST::Instruction.new( :op('invokestatic'),
911+
$TYPE_OPS, 'istrue', 'Long', $TYPE_SMO, $TYPE_TC ));
912+
$il.append(JAST::Instruction.new( :op('lstore'), $t ));
913+
914+
my $have_middle_child := 1;
915+
my $bres;
916+
while $have_middle_child {
917+
my $bpast := nqp::shift(@childlist);
918+
$bres := $qastcomp.as_jast($bpast, :want($RT_OBJ));
919+
$il.append($bres.jast);
920+
$*STACK.obtain($il, $bres);
921+
$il.append($DUP);
922+
$il.append(JAST::Instruction.new( :op('astore'), $b ));
923+
$il.append($ALOAD_1);
924+
$il.append(JAST::Instruction.new( :op('invokestatic'),
925+
$TYPE_OPS, 'istrue', 'Long', $TYPE_SMO, $TYPE_TC ));
926+
$il.append(JAST::Instruction.new( :op('lstore'), $u ));
927+
$il.append($L2I);
928+
$il.append(JAST::Instruction.new( :op('lload'), $t ));
929+
$il.append($L2I);
930+
$il.append($IAND);
931+
$il.append(JAST::Instruction.new( :op('ifne'), $falselabel ));
932+
933+
if @childlist {
934+
my $truelabel := JAST::Label.new(:name('xor_true'));
935+
$il.append(JAST::Instruction.new( :op('lload'), $t ));
936+
$il.append($L2I);
937+
$il.append(JAST::Instruction.new( :op('ifne'), $truelabel ));
938+
$il.append(JAST::Instruction.new( :op('aload'), $b ));
939+
$il.append(JAST::Instruction.new( :op('astore'), $r ));
940+
$il.append(JAST::Instruction.new( :op('lload'), $u ));
941+
$il.append(JAST::Instruction.new( :op('lstore'), $t ));
942+
$il.append($truelabel);
943+
}
944+
else {
945+
$have_middle_child := 0;
946+
}
947+
}
948+
949+
$il.append(JAST::Instruction.new( :op('lload'), $t ));
950+
$il.append($L2I);
951+
$il.append(JAST::Instruction.new( :op('ifne'), $endlabel ));
952+
$il.append(JAST::Instruction.new( :op('aload'), $b ));
953+
$il.append(JAST::Instruction.new( :op('astore'), $r ));
954+
$il.append(JAST::Instruction.new( :op('goto'), $endlabel ));
955+
$il.append($falselabel);
956+
957+
if $fpast {
958+
my $fres := $qastcomp.as_jast($fpast, :want($RT_OBJ));
959+
$il.append($fres.jast);
960+
$*STACK.obtain($il, $fres);
961+
$il.append(JAST::Instruction.new( :op('astore'), $r ));
962+
}
963+
else {
964+
$il.append($ACONST_NULL);
965+
$il.append(JAST::Instruction.new( :op('astore'), $r ));
966+
}
967+
968+
$il.append($endlabel);
969+
$il.append(JAST::Instruction.new( :op('aload'), $r ));
970+
result($il, $RT_OBJ)
971+
});
972+
880973
QAST::OperationsJAST.add_core_op('ifnull', -> $qastcomp, $op {
881974
if +$op.list != 2 {
882975
nqp::die("The 'ifnull' op expects two children");

0 commit comments

Comments
 (0)