@@ -18,6 +18,7 @@ my $SWAP := JAST::Instruction.new( :op('swap') );
18
18
my $ IADD := JAST::Instruction. new ( : op(' iadd' ) );
19
19
my $ LADD := JAST::Instruction. new ( : op(' ladd' ) );
20
20
my $ LSUB := JAST::Instruction. new ( : op(' lsub' ) );
21
+ my $ IAND := JAST::Instruction. new ( : op(' iand' ) );
21
22
my $ I2L := JAST::Instruction. new ( : op(' i2l' ) );
22
23
my $ I2B := JAST::Instruction. new ( : op(' i2b' ) );
23
24
my $ L2I := JAST::Instruction. new ( : op(' l2i' ) );
@@ -877,6 +878,98 @@ QAST::OperationsJAST.add_core_op('defor', -> $qastcomp, $op {
877
878
)))
878
879
});
879
880
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
+
880
973
QAST ::OperationsJAST. add_core_op(' ifnull' , -> $ qastcomp , $ op {
881
974
if + $ op . list != 2 {
882
975
nqp ::die(" The 'ifnull' op expects two children" );
0 commit comments