Home | History | Annotate | Download | only in smali
      1 # Copyright (C) 2017 The Android Open Source Project
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #      http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 
     15 .class public LSmaliTests;
     16 .super Ljava/lang/Object;
     17 
     18 #
     19 # Test transformation of Not/Not/And into Or/Not.
     20 #
     21 
     22 ## CHECK-START: int SmaliTests.$opt$noinline$andToOr(int, int) instruction_simplifier (before)
     23 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
     24 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
     25 ## CHECK-DAG:       <<Not1:i\d+>>        Not [<<P1>>]
     26 ## CHECK-DAG:       <<Not2:i\d+>>        Not [<<P2>>]
     27 ## CHECK-DAG:       <<And:i\d+>>         And [<<Not1>>,<<Not2>>]
     28 ## CHECK-DAG:                            Return [<<And>>]
     29 
     30 ## CHECK-START: int SmaliTests.$opt$noinline$andToOr(int, int) instruction_simplifier (after)
     31 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
     32 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
     33 ## CHECK-DAG:       <<Or:i\d+>>          Or [<<P1>>,<<P2>>]
     34 ## CHECK-DAG:       <<Not:i\d+>>         Not [<<Or>>]
     35 ## CHECK-DAG:                            Return [<<Not>>]
     36 
     37 ## CHECK-START: int SmaliTests.$opt$noinline$andToOr(int, int) instruction_simplifier (after)
     38 ## CHECK-DAG:                            Not
     39 ## CHECK-NOT:                            Not
     40 
     41 ## CHECK-START: int SmaliTests.$opt$noinline$andToOr(int, int) instruction_simplifier (after)
     42 ## CHECK-NOT:                            And
     43 .method public static $opt$noinline$andToOr(II)I
     44     .registers 4
     45     .param p0, "a"    # I
     46     .param p1, "b"    # I
     47 
     48     .prologue
     49     sget-boolean v0, LSmaliTests;->doThrow:Z
     50     if-eqz v0, :cond_a
     51     new-instance v0, Ljava/lang/Error;
     52     invoke-direct {v0}, Ljava/lang/Error;-><init>()V
     53     throw v0
     54 
     55   :cond_a
     56     # return ~a & ~b;
     57     not-int v0, p0
     58     not-int v1, p1
     59     and-int/2addr v0, v1
     60 
     61     return v0
     62 .end method
     63 
     64 # Test transformation of Not/Not/And into Or/Not for boolean negations.
     65 # Note that the graph before this instruction simplification pass does not
     66 # contain `HBooleanNot` instructions. This is because this transformation
     67 # follows the optimization of `HSelect` to `HBooleanNot` occurring in the
     68 # same pass.
     69 
     70 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier (before)
     71 ## CHECK-DAG:       <<P1:z\d+>>          ParameterValue
     72 ## CHECK-DAG:       <<P2:z\d+>>          ParameterValue
     73 ## CHECK-DAG:       <<Const1:i\d+>>      IntConstant 1
     74 ## CHECK-DAG:       <<NotP1:i\d+>>       Xor [<<P1>>,<<Const1>>]
     75 ## CHECK-DAG:       <<NotP2:i\d+>>       Xor [<<P2>>,<<Const1>>]
     76 ## CHECK-DAG:       <<And:i\d+>>         And [<<NotP1>>,<<NotP2>>]
     77 ## CHECK-DAG:                            Return [<<And>>]
     78 
     79 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier (after)
     80 ## CHECK-DAG:       <<Cond1:z\d+>>       ParameterValue
     81 ## CHECK-DAG:       <<Cond2:z\d+>>       ParameterValue
     82 ## CHECK-DAG:       <<Or:i\d+>>          Or [<<Cond1>>,<<Cond2>>]
     83 ## CHECK-DAG:       <<BooleanNot:z\d+>>  BooleanNot [<<Or>>]
     84 ## CHECK-DAG:                            Return [<<BooleanNot>>]
     85 
     86 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier$after_bce (after)
     87 ## CHECK-DAG:                            BooleanNot
     88 ## CHECK-NOT:                            BooleanNot
     89 
     90 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier$after_bce (after)
     91 ## CHECK-NOT:                            And
     92 .method public static $opt$noinline$booleanAndToOr(ZZ)Z
     93     .registers 4
     94     .param p0, "a"    # Z
     95     .param p1, "b"    # Z
     96 
     97     .prologue
     98     sget-boolean v0, LSmaliTests;->doThrow:Z
     99     if-eqz v0, :cond_a
    100     new-instance v0, Ljava/lang/Error;
    101     invoke-direct {v0}, Ljava/lang/Error;-><init>()V
    102     throw v0
    103 
    104   :cond_a
    105     # return !a & !b;
    106     xor-int/lit8 v0, p0, 0x1
    107     xor-int/lit8 v1, p1, 0x1
    108     and-int/2addr v0, v1
    109     return v0
    110 .end method
    111 
    112 # Test transformation of Not/Not/Or into And/Not.
    113 
    114 ## CHECK-START: long SmaliTests.$opt$noinline$orToAnd(long, long) instruction_simplifier (before)
    115 ## CHECK-DAG:       <<P1:j\d+>>          ParameterValue
    116 ## CHECK-DAG:       <<P2:j\d+>>          ParameterValue
    117 ## CHECK-DAG:       <<Not1:j\d+>>        Not [<<P1>>]
    118 ## CHECK-DAG:       <<Not2:j\d+>>        Not [<<P2>>]
    119 ## CHECK-DAG:       <<Or:j\d+>>          Or [<<Not1>>,<<Not2>>]
    120 ## CHECK-DAG:                            Return [<<Or>>]
    121 
    122 ## CHECK-START: long SmaliTests.$opt$noinline$orToAnd(long, long) instruction_simplifier (after)
    123 ## CHECK-DAG:       <<P1:j\d+>>          ParameterValue
    124 ## CHECK-DAG:       <<P2:j\d+>>          ParameterValue
    125 ## CHECK-DAG:       <<And:j\d+>>         And [<<P1>>,<<P2>>]
    126 ## CHECK-DAG:       <<Not:j\d+>>         Not [<<And>>]
    127 ## CHECK-DAG:                            Return [<<Not>>]
    128 
    129 ## CHECK-START: long SmaliTests.$opt$noinline$orToAnd(long, long) instruction_simplifier (after)
    130 ## CHECK-DAG:                            Not
    131 ## CHECK-NOT:                            Not
    132 
    133 ## CHECK-START: long SmaliTests.$opt$noinline$orToAnd(long, long) instruction_simplifier (after)
    134 ## CHECK-NOT:                            Or
    135 .method public static $opt$noinline$orToAnd(JJ)J
    136     .registers 8
    137     .param p0, "a"    # J
    138     .param p2, "b"    # J
    139 
    140     .prologue
    141     sget-boolean v0, LSmaliTests;->doThrow:Z
    142     if-eqz v0, :cond_a
    143     new-instance v0, Ljava/lang/Error;
    144     invoke-direct {v0}, Ljava/lang/Error;-><init>()V
    145     throw v0
    146 
    147   :cond_a
    148     # return ~a | ~b;
    149     not-long v0, p0
    150     not-long v2, p2
    151     or-long/2addr v0, v2
    152     return-wide v0
    153 .end method
    154 
    155 # Test transformation of Not/Not/Or into Or/And for boolean negations.
    156 # Note that the graph before this instruction simplification pass does not
    157 # contain `HBooleanNot` instructions. This is because this transformation
    158 # follows the optimization of `HSelect` to `HBooleanNot` occurring in the
    159 # same pass.
    160 
    161 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier (before)
    162 ## CHECK-DAG:       <<P1:z\d+>>          ParameterValue
    163 ## CHECK-DAG:       <<P2:z\d+>>          ParameterValue
    164 ## CHECK-DAG:       <<Const1:i\d+>>      IntConstant 1
    165 ## CHECK-DAG:       <<NotP1:i\d+>>       Xor [<<P1>>,<<Const1>>]
    166 ## CHECK-DAG:       <<NotP2:i\d+>>       Xor [<<P2>>,<<Const1>>]
    167 ## CHECK-DAG:       <<Or:i\d+>>          Or [<<NotP1>>,<<NotP2>>]
    168 ## CHECK-DAG:                            Return [<<Or>>]
    169 
    170 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier (after)
    171 ## CHECK-DAG:       <<Cond1:z\d+>>       ParameterValue
    172 ## CHECK-DAG:       <<Cond2:z\d+>>       ParameterValue
    173 ## CHECK-DAG:       <<And:i\d+>>         And [<<Cond1>>,<<Cond2>>]
    174 ## CHECK-DAG:       <<BooleanNot:z\d+>>  BooleanNot [<<And>>]
    175 ## CHECK-DAG:                            Return [<<BooleanNot>>]
    176 
    177 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier$after_bce (after)
    178 ## CHECK-DAG:                            BooleanNot
    179 ## CHECK-NOT:                            BooleanNot
    180 
    181 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier$after_bce (after)
    182 ## CHECK-NOT:                            Or
    183 .method public static $opt$noinline$booleanOrToAnd(ZZ)Z
    184     .registers 4
    185     .param p0, "a"    # Z
    186     .param p1, "b"    # Z
    187 
    188     .prologue
    189     sget-boolean v0, LSmaliTests;->doThrow:Z
    190     if-eqz v0, :cond_a
    191     new-instance v0, Ljava/lang/Error;
    192     invoke-direct {v0}, Ljava/lang/Error;-><init>()V
    193     throw v0
    194 
    195   :cond_a
    196     # return !a | !b;
    197     xor-int/lit8 v0, p0, 0x1
    198     xor-int/lit8 v1, p1, 0x1
    199     or-int/2addr v0, v1
    200     return v0
    201 .end method
    202 
    203 # Test that the transformation copes with inputs being separated from the
    204 # bitwise operations.
    205 # This is a regression test. The initial logic was inserting the new bitwise
    206 # operation incorrectly.
    207 
    208 ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (before)
    209 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    210 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    211 ## CHECK-DAG:       <<Cst1:i\d+>>        IntConstant 1
    212 ## CHECK-DAG:       <<AddP1:i\d+>>       Add [<<P1>>,<<Cst1>>]
    213 ## CHECK-DAG:       <<Not1:i\d+>>        Not [<<AddP1>>]
    214 ## CHECK-DAG:       <<AddP2:i\d+>>       Add [<<P2>>,<<Cst1>>]
    215 ## CHECK-DAG:       <<Not2:i\d+>>        Not [<<AddP2>>]
    216 ## CHECK-DAG:       <<Or:i\d+>>          Or [<<Not1>>,<<Not2>>]
    217 ## CHECK-DAG:                            Return [<<Or>>]
    218 
    219 ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after)
    220 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    221 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    222 ## CHECK-DAG:       <<Cst1:i\d+>>        IntConstant 1
    223 ## CHECK-DAG:       <<AddP1:i\d+>>       Add [<<P1>>,<<Cst1>>]
    224 ## CHECK-DAG:       <<AddP2:i\d+>>       Add [<<P2>>,<<Cst1>>]
    225 ## CHECK-DAG:       <<And:i\d+>>         And [<<AddP1>>,<<AddP2>>]
    226 ## CHECK-DAG:       <<Not:i\d+>>         Not [<<And>>]
    227 ## CHECK-DAG:                            Return [<<Not>>]
    228 
    229 ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after)
    230 ## CHECK-DAG:                            Not
    231 ## CHECK-NOT:                            Not
    232 
    233 ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after)
    234 ## CHECK-NOT:                            Or
    235 .method public static $opt$noinline$regressInputsAway(II)I
    236     .registers 7
    237     .param p0, "a"    # I
    238     .param p1, "b"    # I
    239 
    240     .prologue
    241     sget-boolean v4, LSmaliTests;->doThrow:Z
    242     if-eqz v4, :cond_a
    243     new-instance v4, Ljava/lang/Error;
    244     invoke-direct {v4}, Ljava/lang/Error;-><init>()V
    245     throw v4
    246 
    247   :cond_a
    248     # int a1 = a + 1;
    249     add-int/lit8 v0, p0, 0x1
    250     # int not_a1 = ~a1;
    251     not-int v2, v0
    252     # int b1 = b + 1;
    253     add-int/lit8 v1, p1, 0x1
    254     # int not_b1 = ~b1;
    255     not-int v3, v1
    256 
    257     # return not_a1 | not_b1
    258     or-int v4, v2, v3
    259     return v4
    260 .end method
    261 
    262 # Test transformation of Not/Not/Xor into Xor.
    263 
    264 # See first note above.
    265 ## CHECK-START: int SmaliTests.$opt$noinline$notXorToXor(int, int) instruction_simplifier (before)
    266 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    267 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    268 ## CHECK-DAG:       <<Not1:i\d+>>        Not [<<P1>>]
    269 ## CHECK-DAG:       <<Not2:i\d+>>        Not [<<P2>>]
    270 ## CHECK-DAG:       <<Xor:i\d+>>         Xor [<<Not1>>,<<Not2>>]
    271 ## CHECK-DAG:                            Return [<<Xor>>]
    272 
    273 ## CHECK-START: int SmaliTests.$opt$noinline$notXorToXor(int, int) instruction_simplifier (after)
    274 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    275 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    276 ## CHECK-DAG:       <<Xor:i\d+>>         Xor [<<P1>>,<<P2>>]
    277 ## CHECK-DAG:                            Return [<<Xor>>]
    278 
    279 ## CHECK-START: int SmaliTests.$opt$noinline$notXorToXor(int, int) instruction_simplifier (after)
    280 ## CHECK-NOT:                            Not
    281 .method public static $opt$noinline$notXorToXor(II)I
    282     .registers 4
    283     .param p0, "a"    # I
    284     .param p1, "b"    # I
    285 
    286     .prologue
    287     sget-boolean v0, LSmaliTests;->doThrow:Z
    288     if-eqz v0, :cond_a
    289     new-instance v0, Ljava/lang/Error;
    290     invoke-direct {v0}, Ljava/lang/Error;-><init>()V
    291     throw v0
    292 
    293   :cond_a
    294     # return ~a ^ ~b;
    295     not-int v0, p0
    296     not-int v1, p1
    297     xor-int/2addr v0, v1
    298     return v0
    299 .end method
    300 
    301 # Test transformation of Not/Not/Xor into Xor for boolean negations.
    302 # Note that the graph before this instruction simplification pass does not
    303 # contain `HBooleanNot` instructions. This is because this transformation
    304 # follows the optimization of `HSelect` to `HBooleanNot` occurring in the
    305 # same pass.
    306 
    307 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier (before)
    308 ## CHECK-DAG:       <<P1:z\d+>>          ParameterValue
    309 ## CHECK-DAG:       <<P2:z\d+>>          ParameterValue
    310 ## CHECK-DAG:       <<Const1:i\d+>>      IntConstant 1
    311 ## CHECK-DAG:       <<NotP1:i\d+>>       Xor [<<P1>>,<<Const1>>]
    312 ## CHECK-DAG:       <<NotP2:i\d+>>       Xor [<<P2>>,<<Const1>>]
    313 ## CHECK-DAG:       <<Xor:i\d+>>         Xor [<<NotP1>>,<<NotP2>>]
    314 ## CHECK-DAG:                            Return [<<Xor>>]
    315 
    316 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier (after)
    317 ## CHECK-DAG:       <<Cond1:z\d+>>       ParameterValue
    318 ## CHECK-DAG:       <<Cond2:z\d+>>       ParameterValue
    319 ## CHECK-DAG:       <<Xor:i\d+>>         Xor [<<Cond1>>,<<Cond2>>]
    320 ## CHECK-DAG:                            Return [<<Xor>>]
    321 
    322 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier$after_bce (after)
    323 ## CHECK-NOT:                            BooleanNot
    324 .method public static $opt$noinline$booleanNotXorToXor(ZZ)Z
    325     .registers 4
    326     .param p0, "a"    # Z
    327     .param p1, "b"    # Z
    328 
    329     .prologue
    330     sget-boolean v0, LSmaliTests;->doThrow:Z
    331     if-eqz v0, :cond_a
    332     new-instance v0, Ljava/lang/Error;
    333     invoke-direct {v0}, Ljava/lang/Error;-><init>()V
    334     throw v0
    335 
    336   :cond_a
    337     # return !a ^ !b;
    338     xor-int/lit8 v0, p0, 0x1
    339     xor-int/lit8 v1, p1, 0x1
    340     xor-int/2addr v0, v1
    341     return v0
    342 .end method
    343 
    344 # Check that no transformation is done when one Not has multiple uses.
    345 
    346 ## CHECK-START: int SmaliTests.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (before)
    347 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    348 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    349 ## CHECK-DAG:       <<One:i\d+>>         IntConstant 1
    350 ## CHECK-DAG:       <<Not2:i\d+>>        Not [<<P2>>]
    351 ## CHECK-DAG:       <<And2:i\d+>>        And [<<Not2>>,<<One>>]
    352 ## CHECK-DAG:       <<Not1:i\d+>>        Not [<<P1>>]
    353 ## CHECK-DAG:       <<And1:i\d+>>        And [<<Not1>>,<<Not2>>]
    354 ## CHECK-DAG:       <<Add:i\d+>>         Add [<<And2>>,<<And1>>]
    355 ## CHECK-DAG:                            Return [<<Add>>]
    356 
    357 ## CHECK-START: int SmaliTests.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (after)
    358 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    359 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    360 ## CHECK-DAG:       <<One:i\d+>>         IntConstant 1
    361 ## CHECK-DAG:       <<Not2:i\d+>>        Not [<<P2>>]
    362 ## CHECK-DAG:       <<And2:i\d+>>        And [<<Not2>>,<<One>>]
    363 ## CHECK-DAG:       <<Not1:i\d+>>        Not [<<P1>>]
    364 ## CHECK-DAG:       <<And1:i\d+>>        And [<<Not1>>,<<Not2>>]
    365 ## CHECK-DAG:       <<Add:i\d+>>         Add [<<And2>>,<<And1>>]
    366 ## CHECK-DAG:                            Return [<<Add>>]
    367 
    368 ## CHECK-START: int SmaliTests.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (after)
    369 ## CHECK-NOT:                            Or
    370 .method public static $opt$noinline$notMultipleUses(II)I
    371     .registers 5
    372     .param p0, "a"    # I
    373     .param p1, "b"    # I
    374 
    375     .prologue
    376     sget-boolean v1, LSmaliTests;->doThrow:Z
    377     if-eqz v1, :cond_a
    378     new-instance v1, Ljava/lang/Error;
    379     invoke-direct {v1}, Ljava/lang/Error;-><init>()V
    380     throw v1
    381 
    382   :cond_a
    383     # int tmp = ~b;
    384     not-int v0, p1
    385     # return (tmp & 0x1) + (~a & tmp);
    386     and-int/lit8 v1, v0, 0x1
    387     not-int v2, p0
    388     and-int/2addr v2, v0
    389     add-int/2addr v1, v2
    390     return v1
    391 .end method
    392 
    393 # static fields
    394 .field static doThrow:Z # boolean
    395 
    396 # direct methods
    397 .method static constructor <clinit>()V
    398     .registers 1
    399 
    400     .prologue
    401     # doThrow = false
    402     const/4 v0, 0x0
    403     sput-boolean v0, LSmaliTests;->doThrow:Z
    404     return-void
    405 .end method
    406 
    407 
    408 # Test transformation of Not/Not/And into Or/Not.
    409 
    410 # Note: before the instruction_simplifier pass, Xor's are used instead of
    411 # Not's (the simplification happens during the same pass).
    412 ## CHECK-START: int SmaliTests.$opt$noinline$andToOrV2(int, int) instruction_simplifier (before)
    413 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    414 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    415 ## CHECK-DAG:       <<CstM1:i\d+>>       IntConstant -1
    416 ## CHECK-DAG:       <<Not1:i\d+>>        Xor [<<P1>>,<<CstM1>>]
    417 ## CHECK-DAG:       <<Not2:i\d+>>        Xor [<<P2>>,<<CstM1>>]
    418 ## CHECK-DAG:       <<And:i\d+>>         And [<<Not1>>,<<Not2>>]
    419 ## CHECK-DAG:                            Return [<<And>>]
    420 
    421 ## CHECK-START: int SmaliTests.$opt$noinline$andToOrV2(int, int) instruction_simplifier (after)
    422 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    423 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    424 ## CHECK-DAG:       <<Or:i\d+>>          Or [<<P1>>,<<P2>>]
    425 ## CHECK-DAG:       <<Not:i\d+>>         Not [<<Or>>]
    426 ## CHECK-DAG:                            Return [<<Not>>]
    427 
    428 ## CHECK-START: int SmaliTests.$opt$noinline$andToOrV2(int, int) instruction_simplifier (after)
    429 ## CHECK-DAG:                            Not
    430 ## CHECK-NOT:                            Not
    431 
    432 ## CHECK-START: int SmaliTests.$opt$noinline$andToOrV2(int, int) instruction_simplifier (after)
    433 ## CHECK-NOT:                            And
    434 
    435 # Original java source:
    436 #
    437 #     public static int $opt$noinline$andToOr(int a, int b) {
    438 #       if (doThrow) throw new Error();
    439 #       return ~a & ~b;
    440 #     }
    441 
    442 .method public static $opt$noinline$andToOrV2(II)I
    443     .registers 4
    444     .param p0, "a"    # I
    445     .param p1, "b"    # I
    446 
    447     .prologue
    448     .line 85
    449     sget-boolean v0, LMain;->doThrow:Z
    450 
    451     if-eqz v0, :cond_a
    452 
    453     new-instance v0, Ljava/lang/Error;
    454 
    455     invoke-direct {v0}, Ljava/lang/Error;-><init>()V
    456 
    457     throw v0
    458 
    459     .line 86
    460     :cond_a
    461     xor-int/lit8 v0, p0, -0x1
    462 
    463     xor-int/lit8 v1, p1, -0x1
    464 
    465     and-int/2addr v0, v1
    466 
    467     return v0
    468 .end method
    469 
    470 
    471 # Test transformation of Not/Not/And into Or/Not for boolean negations.
    472 # Note that the graph before this instruction simplification pass does not
    473 # contain `HBooleanNot` instructions. This is because this transformation
    474 # follows the optimization of `HSelect` to `HBooleanNot` occurring in the
    475 # same pass.
    476 
    477 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOrV2(boolean, boolean) instruction_simplifier$after_gvn (before)
    478 ## CHECK-DAG:       <<P1:z\d+>>          ParameterValue
    479 ## CHECK-DAG:       <<P2:z\d+>>          ParameterValue
    480 ## CHECK-DAG:       <<Const0:i\d+>>      IntConstant 0
    481 ## CHECK-DAG:       <<Const1:i\d+>>      IntConstant 1
    482 ## CHECK-DAG:       <<Select1:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P1>>]
    483 ## CHECK-DAG:       <<Select2:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P2>>]
    484 ## CHECK-DAG:       <<And:i\d+>>         And [<<Select1>>,<<Select2>>]
    485 ## CHECK-DAG:                            Return [<<And>>]
    486 
    487 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOrV2(boolean, boolean) instruction_simplifier$after_gvn (after)
    488 ## CHECK-DAG:       <<Cond1:z\d+>>       ParameterValue
    489 ## CHECK-DAG:       <<Cond2:z\d+>>       ParameterValue
    490 ## CHECK-DAG:       <<Or:i\d+>>          Or [<<Cond1>>,<<Cond2>>]
    491 ## CHECK-DAG:       <<BooleanNot:z\d+>>  BooleanNot [<<Or>>]
    492 ## CHECK-DAG:                            Return [<<BooleanNot>>]
    493 
    494 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOrV2(boolean, boolean) instruction_simplifier$after_bce (after)
    495 ## CHECK-DAG:                            BooleanNot
    496 ## CHECK-NOT:                            BooleanNot
    497 
    498 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOrV2(boolean, boolean) instruction_simplifier$after_bce (after)
    499 ## CHECK-NOT:                            And
    500 
    501 # Original java source:
    502 #
    503 #     public static boolean $opt$noinline$booleanAndToOr(boolean a, boolean b) {
    504 #       if (doThrow) throw new Error();
    505 #       return !a & !b;
    506 #     }
    507 
    508 .method public static $opt$noinline$booleanAndToOrV2(ZZ)Z
    509     .registers 5
    510     .param p0, "a"    # Z
    511     .param p1, "b"    # Z
    512 
    513     .prologue
    514     const/4 v0, 0x1
    515 
    516     const/4 v1, 0x0
    517 
    518     .line 122
    519     sget-boolean v2, LMain;->doThrow:Z
    520 
    521     if-eqz v2, :cond_c
    522 
    523     new-instance v0, Ljava/lang/Error;
    524 
    525     invoke-direct {v0}, Ljava/lang/Error;-><init>()V
    526 
    527     throw v0
    528 
    529     .line 123
    530     :cond_c
    531     if-nez p0, :cond_13
    532 
    533     move v2, v0
    534 
    535     :goto_f
    536     if-nez p1, :cond_15
    537 
    538     :goto_11
    539     and-int/2addr v0, v2
    540 
    541     return v0
    542 
    543     :cond_13
    544     move v2, v1
    545 
    546     goto :goto_f
    547 
    548     :cond_15
    549     move v0, v1
    550 
    551     goto :goto_11
    552 .end method
    553 
    554 
    555 # Test transformation of Not/Not/Or into And/Not.
    556 
    557 # See note above.
    558 # The second Xor has its arguments reversed for no obvious reason.
    559 ## CHECK-START: long SmaliTests.$opt$noinline$orToAndV2(long, long) instruction_simplifier (before)
    560 ## CHECK-DAG:       <<P1:j\d+>>          ParameterValue
    561 ## CHECK-DAG:       <<P2:j\d+>>          ParameterValue
    562 ## CHECK-DAG:       <<CstM1:j\d+>>       LongConstant -1
    563 ## CHECK-DAG:       <<Not1:j\d+>>        Xor [<<P1>>,<<CstM1>>]
    564 ## CHECK-DAG:       <<Not2:j\d+>>        Xor [<<CstM1>>,<<P2>>]
    565 ## CHECK-DAG:       <<Or:j\d+>>          Or [<<Not1>>,<<Not2>>]
    566 ## CHECK-DAG:                            Return [<<Or>>]
    567 
    568 ## CHECK-START: long SmaliTests.$opt$noinline$orToAndV2(long, long) instruction_simplifier (after)
    569 ## CHECK-DAG:       <<P1:j\d+>>          ParameterValue
    570 ## CHECK-DAG:       <<P2:j\d+>>          ParameterValue
    571 ## CHECK-DAG:       <<And:j\d+>>         And [<<P1>>,<<P2>>]
    572 ## CHECK-DAG:       <<Not:j\d+>>         Not [<<And>>]
    573 ## CHECK-DAG:                            Return [<<Not>>]
    574 
    575 ## CHECK-START: long SmaliTests.$opt$noinline$orToAndV2(long, long) instruction_simplifier (after)
    576 ## CHECK-DAG:                            Not
    577 ## CHECK-NOT:                            Not
    578 
    579 ## CHECK-START: long SmaliTests.$opt$noinline$orToAndV2(long, long) instruction_simplifier (after)
    580 ## CHECK-NOT:                            Or
    581 
    582 # Original java source:
    583 #
    584 #     public static long $opt$noinline$orToAnd(long a, long b) {
    585 #       if (doThrow) throw new Error();
    586 #       return ~a | ~b;
    587 #     }
    588 
    589 .method public static $opt$noinline$orToAndV2(JJ)J
    590     .registers 8
    591     .param p0, "a"    # J
    592     .param p2, "b"    # J
    593 
    594     .prologue
    595     const-wide/16 v2, -0x1
    596 
    597     .line 156
    598     sget-boolean v0, LMain;->doThrow:Z
    599 
    600     if-eqz v0, :cond_c
    601 
    602     new-instance v0, Ljava/lang/Error;
    603 
    604     invoke-direct {v0}, Ljava/lang/Error;-><init>()V
    605 
    606     throw v0
    607 
    608     .line 157
    609     :cond_c
    610     xor-long v0, p0, v2
    611 
    612     xor-long/2addr v2, p2
    613 
    614     or-long/2addr v0, v2
    615 
    616     return-wide v0
    617 .end method
    618 
    619 # Test transformation of Not/Not/Or into Or/And for boolean negations.
    620 # Note that the graph before this instruction simplification pass does not
    621 # contain `HBooleanNot` instructions. This is because this transformation
    622 # follows the optimization of `HSelect` to `HBooleanNot` occurring in the
    623 # same pass.
    624 
    625 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAndV2(boolean, boolean) instruction_simplifier$after_gvn (before)
    626 ## CHECK-DAG:       <<P1:z\d+>>          ParameterValue
    627 ## CHECK-DAG:       <<P2:z\d+>>          ParameterValue
    628 ## CHECK-DAG:       <<Const0:i\d+>>      IntConstant 0
    629 ## CHECK-DAG:       <<Const1:i\d+>>      IntConstant 1
    630 ## CHECK-DAG:       <<Select1:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P1>>]
    631 ## CHECK-DAG:       <<Select2:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P2>>]
    632 ## CHECK-DAG:       <<Or:i\d+>>          Or [<<Select1>>,<<Select2>>]
    633 ## CHECK-DAG:                            Return [<<Or>>]
    634 
    635 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAndV2(boolean, boolean) instruction_simplifier$after_gvn (after)
    636 ## CHECK-DAG:       <<Cond1:z\d+>>       ParameterValue
    637 ## CHECK-DAG:       <<Cond2:z\d+>>       ParameterValue
    638 ## CHECK-DAG:       <<And:i\d+>>         And [<<Cond1>>,<<Cond2>>]
    639 ## CHECK-DAG:       <<BooleanNot:z\d+>>  BooleanNot [<<And>>]
    640 ## CHECK-DAG:                            Return [<<BooleanNot>>]
    641 
    642 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAndV2(boolean, boolean) instruction_simplifier$after_bce (after)
    643 ## CHECK-DAG:                            BooleanNot
    644 ## CHECK-NOT:                            BooleanNot
    645 
    646 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAndV2(boolean, boolean) instruction_simplifier$after_bce (after)
    647 ## CHECK-NOT:                            Or
    648 
    649 # Original java source:
    650 #
    651 #     public static boolean $opt$noinline$booleanOrToAnd(boolean a, boolean b) {
    652 #       if (doThrow) throw new Error();
    653 #       return !a | !b;
    654 #     }
    655 
    656 .method public static $opt$noinline$booleanOrToAndV2(ZZ)Z
    657     .registers 5
    658     .param p0, "a"    # Z
    659     .param p1, "b"    # Z
    660 
    661     .prologue
    662     const/4 v0, 0x1
    663 
    664     const/4 v1, 0x0
    665 
    666     .line 193
    667     sget-boolean v2, LMain;->doThrow:Z
    668 
    669     if-eqz v2, :cond_c
    670 
    671     new-instance v0, Ljava/lang/Error;
    672 
    673     invoke-direct {v0}, Ljava/lang/Error;-><init>()V
    674 
    675     throw v0
    676 
    677     .line 194
    678     :cond_c
    679     if-nez p0, :cond_13
    680 
    681     move v2, v0
    682 
    683     :goto_f
    684     if-nez p1, :cond_15
    685 
    686     :goto_11
    687     or-int/2addr v0, v2
    688 
    689     return v0
    690 
    691     :cond_13
    692     move v2, v1
    693 
    694     goto :goto_f
    695 
    696     :cond_15
    697     move v0, v1
    698 
    699     goto :goto_11
    700 .end method
    701 
    702 
    703 # Test that the transformation copes with inputs being separated from the
    704 # bitwise operations.
    705 # This is a regression test. The initial logic was inserting the new bitwise
    706 # operation incorrectly.
    707 
    708 ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAwayV2(int, int) instruction_simplifier (before)
    709 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    710 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    711 ## CHECK-DAG:       <<Cst1:i\d+>>        IntConstant 1
    712 ## CHECK-DAG:       <<CstM1:i\d+>>       IntConstant -1
    713 ## CHECK-DAG:       <<AddP1:i\d+>>       Add [<<P1>>,<<Cst1>>]
    714 ## CHECK-DAG:       <<Not1:i\d+>>        Xor [<<AddP1>>,<<CstM1>>]
    715 ## CHECK-DAG:       <<AddP2:i\d+>>       Add [<<P2>>,<<Cst1>>]
    716 ## CHECK-DAG:       <<Not2:i\d+>>        Xor [<<AddP2>>,<<CstM1>>]
    717 ## CHECK-DAG:       <<Or:i\d+>>          Or [<<Not1>>,<<Not2>>]
    718 ## CHECK-DAG:                            Return [<<Or>>]
    719 
    720 ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAwayV2(int, int) instruction_simplifier (after)
    721 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    722 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    723 ## CHECK-DAG:       <<Cst1:i\d+>>        IntConstant 1
    724 ## CHECK-DAG:       <<AddP1:i\d+>>       Add [<<P1>>,<<Cst1>>]
    725 ## CHECK-DAG:       <<AddP2:i\d+>>       Add [<<P2>>,<<Cst1>>]
    726 ## CHECK-DAG:       <<And:i\d+>>         And [<<AddP1>>,<<AddP2>>]
    727 ## CHECK-DAG:       <<Not:i\d+>>         Not [<<And>>]
    728 ## CHECK-DAG:                            Return [<<Not>>]
    729 
    730 ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAwayV2(int, int) instruction_simplifier (after)
    731 ## CHECK-DAG:                            Not
    732 ## CHECK-NOT:                            Not
    733 
    734 ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAwayV2(int, int) instruction_simplifier (after)
    735 ## CHECK-NOT:                            Or
    736 
    737 # Original java source:
    738 #
    739 #     public static int $opt$noinline$regressInputsAway(int a, int b) {
    740 #       if (doThrow) throw new Error();
    741 #       int a1 = a + 1;
    742 #       int not_a1 = ~a1;
    743 #       int b1 = b + 1;
    744 #       int not_b1 = ~b1;
    745 #       return not_a1 | not_b1;
    746 #     }
    747 
    748 .method public static $opt$noinline$regressInputsAwayV2(II)I
    749     .registers 7
    750     .param p0, "a"    # I
    751     .param p1, "b"    # I
    752 
    753     .prologue
    754     .line 234
    755     sget-boolean v4, LMain;->doThrow:Z
    756 
    757     if-eqz v4, :cond_a
    758 
    759     new-instance v4, Ljava/lang/Error;
    760 
    761     invoke-direct {v4}, Ljava/lang/Error;-><init>()V
    762 
    763     throw v4
    764 
    765     .line 235
    766     :cond_a
    767     add-int/lit8 v0, p0, 0x1
    768 
    769     .line 236
    770     .local v0, "a1":I
    771     xor-int/lit8 v2, v0, -0x1
    772 
    773     .line 237
    774     .local v2, "not_a1":I
    775     add-int/lit8 v1, p1, 0x1
    776 
    777     .line 238
    778     .local v1, "b1":I
    779     xor-int/lit8 v3, v1, -0x1
    780 
    781     .line 239
    782     .local v3, "not_b1":I
    783     or-int v4, v2, v3
    784 
    785     return v4
    786 .end method
    787 
    788 
    789 # Test transformation of Not/Not/Xor into Xor.
    790 
    791 # See first note above.
    792 ## CHECK-START: int SmaliTests.$opt$noinline$notXorToXorV2(int, int) instruction_simplifier (before)
    793 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    794 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    795 ## CHECK-DAG:       <<CstM1:i\d+>>       IntConstant -1
    796 ## CHECK-DAG:       <<Not1:i\d+>>        Xor [<<P1>>,<<CstM1>>]
    797 ## CHECK-DAG:       <<Not2:i\d+>>        Xor [<<P2>>,<<CstM1>>]
    798 ## CHECK-DAG:       <<Xor:i\d+>>         Xor [<<Not1>>,<<Not2>>]
    799 ## CHECK-DAG:                            Return [<<Xor>>]
    800 
    801 ## CHECK-START: int SmaliTests.$opt$noinline$notXorToXorV2(int, int) instruction_simplifier (after)
    802 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    803 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    804 ## CHECK-DAG:       <<Xor:i\d+>>         Xor [<<P1>>,<<P2>>]
    805 ## CHECK-DAG:                            Return [<<Xor>>]
    806 
    807 ## CHECK-START: int SmaliTests.$opt$noinline$notXorToXorV2(int, int) instruction_simplifier (after)
    808 ## CHECK-NOT:                            Not
    809 
    810 # Original java source:
    811 #
    812 #     public static int $opt$noinline$notXorToXor(int a, int b) {
    813 #       if (doThrow) throw new Error();
    814 #       return ~a ^ ~b;
    815 #     }
    816 
    817 .method public static $opt$noinline$notXorToXorV2(II)I
    818     .registers 4
    819     .param p0, "a"    # I
    820     .param p1, "b"    # I
    821 
    822     .prologue
    823     .line 266
    824     sget-boolean v0, LMain;->doThrow:Z
    825 
    826     if-eqz v0, :cond_a
    827 
    828     new-instance v0, Ljava/lang/Error;
    829 
    830     invoke-direct {v0}, Ljava/lang/Error;-><init>()V
    831 
    832     throw v0
    833 
    834     .line 267
    835     :cond_a
    836     xor-int/lit8 v0, p0, -0x1
    837 
    838     xor-int/lit8 v1, p1, -0x1
    839 
    840     xor-int/2addr v0, v1
    841 
    842     return v0
    843 .end method
    844 
    845 
    846 # Test transformation of Not/Not/Xor into Xor for boolean negations.
    847 # Note that the graph before this instruction simplification pass does not
    848 # contain `HBooleanNot` instructions. This is because this transformation
    849 # follows the optimization of `HSelect` to `HBooleanNot` occurring in the
    850 # same pass.
    851 
    852 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanNotXorToXorV2(boolean, boolean) instruction_simplifier$after_gvn (before)
    853 ## CHECK-DAG:       <<P1:z\d+>>          ParameterValue
    854 ## CHECK-DAG:       <<P2:z\d+>>          ParameterValue
    855 ## CHECK-DAG:       <<Const0:i\d+>>      IntConstant 0
    856 ## CHECK-DAG:       <<Const1:i\d+>>      IntConstant 1
    857 ## CHECK-DAG:       <<Select1:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P1>>]
    858 ## CHECK-DAG:       <<Select2:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P2>>]
    859 ## CHECK-DAG:       <<Xor:i\d+>>         Xor [<<Select1>>,<<Select2>>]
    860 ## CHECK-DAG:                            Return [<<Xor>>]
    861 
    862 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanNotXorToXorV2(boolean, boolean) instruction_simplifier$after_gvn (after)
    863 ## CHECK-DAG:       <<Cond1:z\d+>>       ParameterValue
    864 ## CHECK-DAG:       <<Cond2:z\d+>>       ParameterValue
    865 ## CHECK-DAG:       <<Xor:i\d+>>         Xor [<<Cond1>>,<<Cond2>>]
    866 ## CHECK-DAG:                            Return [<<Xor>>]
    867 
    868 ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanNotXorToXorV2(boolean, boolean) instruction_simplifier$after_bce (after)
    869 ## CHECK-NOT:                            BooleanNot
    870 
    871 # Original java source:
    872 #
    873 #     public static boolean $opt$noinline$booleanNotXorToXor(boolean a, boolean b) {
    874 #       if (doThrow) throw new Error();
    875 #       return !a ^ !b;
    876 #     }
    877 
    878 .method public static $opt$noinline$booleanNotXorToXorV2(ZZ)Z
    879     .registers 5
    880     .param p0, "a"    # Z
    881     .param p1, "b"    # Z
    882 
    883     .prologue
    884     const/4 v0, 0x1
    885 
    886     const/4 v1, 0x0
    887 
    888     .line 298
    889     sget-boolean v2, LMain;->doThrow:Z
    890 
    891     if-eqz v2, :cond_c
    892 
    893     new-instance v0, Ljava/lang/Error;
    894 
    895     invoke-direct {v0}, Ljava/lang/Error;-><init>()V
    896 
    897     throw v0
    898 
    899     .line 299
    900     :cond_c
    901     if-nez p0, :cond_13
    902 
    903     move v2, v0
    904 
    905     :goto_f
    906     if-nez p1, :cond_15
    907 
    908     :goto_11
    909     xor-int/2addr v0, v2
    910 
    911     return v0
    912 
    913     :cond_13
    914     move v2, v1
    915 
    916     goto :goto_f
    917 
    918     :cond_15
    919     move v0, v1
    920 
    921     goto :goto_11
    922 .end method
    923 
    924 
    925 # Check that no transformation is done when one Not has multiple uses.
    926 
    927 ## CHECK-START: int SmaliTests.$opt$noinline$notMultipleUsesV2(int, int) instruction_simplifier (before)
    928 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    929 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    930 ## CHECK-DAG:       <<CstM1:i\d+>>       IntConstant -1
    931 ## CHECK-DAG:       <<One:i\d+>>         IntConstant 1
    932 ## CHECK-DAG:       <<Not2:i\d+>>        Xor [<<P2>>,<<CstM1>>]
    933 ## CHECK-DAG:       <<And2:i\d+>>        And [<<Not2>>,<<One>>]
    934 ## CHECK-DAG:       <<Not1:i\d+>>        Xor [<<P1>>,<<CstM1>>]
    935 ## CHECK-DAG:       <<And1:i\d+>>        And [<<Not1>>,<<Not2>>]
    936 ## CHECK-DAG:       <<Add:i\d+>>         Add [<<And2>>,<<And1>>]
    937 ## CHECK-DAG:                            Return [<<Add>>]
    938 
    939 ## CHECK-START: int SmaliTests.$opt$noinline$notMultipleUsesV2(int, int) instruction_simplifier (after)
    940 ## CHECK-DAG:       <<P1:i\d+>>          ParameterValue
    941 ## CHECK-DAG:       <<P2:i\d+>>          ParameterValue
    942 ## CHECK-DAG:       <<One:i\d+>>         IntConstant 1
    943 ## CHECK-DAG:       <<Not2:i\d+>>        Not [<<P2>>]
    944 ## CHECK-DAG:       <<And2:i\d+>>        And [<<Not2>>,<<One>>]
    945 ## CHECK-DAG:       <<Not1:i\d+>>        Not [<<P1>>]
    946 ## CHECK-DAG:       <<And1:i\d+>>        And [<<Not1>>,<<Not2>>]
    947 ## CHECK-DAG:       <<Add:i\d+>>         Add [<<And2>>,<<And1>>]
    948 ## CHECK-DAG:                            Return [<<Add>>]
    949 
    950 ## CHECK-START: int SmaliTests.$opt$noinline$notMultipleUsesV2(int, int) instruction_simplifier (after)
    951 ## CHECK-NOT:                            Or
    952 
    953 # Original java source:
    954 #
    955 #     public static int $opt$noinline$notMultipleUses(int a, int b) {
    956 #       if (doThrow) throw new Error();
    957 #       int tmp = ~b;
    958 #       return (tmp & 0x1) + (~a & tmp);
    959 #     }
    960 
    961 .method public static $opt$noinline$notMultipleUsesV2(II)I
    962     .registers 5
    963     .param p0, "a"    # I
    964     .param p1, "b"    # I
    965 
    966     .prologue
    967     .line 333
    968     sget-boolean v1, LMain;->doThrow:Z
    969 
    970     if-eqz v1, :cond_a
    971 
    972     new-instance v1, Ljava/lang/Error;
    973 
    974     invoke-direct {v1}, Ljava/lang/Error;-><init>()V
    975 
    976     throw v1
    977 
    978     .line 334
    979     :cond_a
    980     xor-int/lit8 v0, p1, -0x1
    981 
    982     .line 335
    983     .local v0, "tmp":I
    984     and-int/lit8 v1, v0, 0x1
    985 
    986     xor-int/lit8 v2, p0, -0x1
    987 
    988     and-int/2addr v2, v0
    989 
    990     add-int/2addr v1, v2
    991 
    992     return v1
    993 .end method
    994