Factory.cpp revision c6f1066fd2dd761349128a9f422bc1ce3c3de595
19bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee/*
29bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * Copyright (C) 2009 The Android Open Source Project
39bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee *
49bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * Licensed under the Apache License, Version 2.0 (the "License");
59bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * you may not use this file except in compliance with the License.
69bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * You may obtain a copy of the License at
79bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee *
89bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee *      http://www.apache.org/licenses/LICENSE-2.0
99bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee *
109bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * Unless required by applicable law or agreed to in writing, software
119bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * distributed under the License is distributed on an "AS IS" BASIS,
129bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * See the License for the specific language governing permissions and
149bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * limitations under the License.
159bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee */
169bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee
179bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee/*
189bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee * This file contains codegen for the Thumb ISA and is intended to be
19270c1d64a192341be842f46734054c692bac061eBill Buzbee * includes by:
209bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee *
219bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee *        Codegen-$(TARGET_ARCH_VARIANT).c
229bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee *
239bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee */
249bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee
255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int coreTemps[] = {r0, r1, r2, r3, r4PC, r7, r8, r9, r10, r11, r12};
265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int corePreserved[] = {};
275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int fpTemps[] = {fr16, fr17, fr18, fr19, fr20, fr21, fr22, fr23,
28c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                        fr24, fr25, fr26, fr27, fr28, fr29, fr30, fr31};
295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int fpPreserved[] = {};
305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeImmSingle(int value)
325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{
335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int res;
345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int bitA =    (value & 0x80000000) >> 31;
355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int notBitB = (value & 0x40000000) >> 30;
365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int bitB =    (value & 0x20000000) >> 29;
375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int bSmear =  (value & 0x3e000000) >> 25;
385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int slice =   (value & 0x01f80000) >> 19;
395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int zeroes =  (value & 0x0007ffff);
405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (zeroes != 0)
415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        return -1;
425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (bitB) {
435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        if ((notBitB != 0) || (bSmear != 0x1f))
445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            return -1;
455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    } else {
465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        if ((notBitB != 1) || (bSmear != 0x0))
475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            return -1;
485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    res = (bitA << 7) | (bitB << 6) | slice;
505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return res;
515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng}
525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadFPConstantValue(CompilationUnit *cUnit, int rDest,
545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                                   int value)
555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{
565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int encodedImm = encodeImmSingle(value);
575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    assert(SINGLEREG(rDest));
585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (encodedImm >= 0) {
595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        return newLIR2(cUnit, kThumb2Vmovs_IMM8, rDest, encodedImm);
605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    ArmLIR *dataTarget = scanLiteralPool(cUnit, value, 0);
625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (dataTarget == NULL) {
635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        dataTarget = addWordData(cUnit, value, false);
645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    ArmLIR *loadPcRel = dvmCompilerNew(sizeof(ArmLIR), true);
665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    loadPcRel->opCode = kThumb2Vldrs;
675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    loadPcRel->generic.target = (LIR *) dataTarget;
685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    loadPcRel->operands[0] = rDest;
695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    loadPcRel->operands[1] = rpc;
705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    setupResourceMasks(loadPcRel);
715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel);
725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return loadPcRel;
735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng}
741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic int leadingZeros(u4 val)
761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    u4 alt;
781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    int n;
791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    int count;
801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    count = 16;
821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    n = 32;
831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    do {
841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        alt = val >> count;
851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        if (alt != 0) {
861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            n = n - count;
871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            val = alt;
881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        }
891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        count >>= 1;
901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    } while (count);
911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return n - val;
921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
939bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee
949bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee/*
951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * Determine whether value can be encoded as a Thumb2 modified
961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * immediate.  If not, return -1.  If so, return i:imm3:a:bcdefgh form.
979bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee */
981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic int modifiedImmediate(u4 value)
991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
1001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   int zLeading;
1011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   int zTrailing;
1021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   u4 b0 = value & 0xff;
1031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
1041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   /* Note: case of value==0 must use 0:000:0:0000000 encoding */
1051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   if (value <= 0xFF)
1061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee       return b0;  // 0:000:a:bcdefgh
1071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   if (value == ((b0 << 16) | b0))
1081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee       return (0x1 << 8) | b0; /* 0:001:a:bcdefgh */
1091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   if (value == ((b0 << 24) | (b0 << 16) | (b0 << 8) | b0))
1101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee       return (0x3 << 8) | b0; /* 0:011:a:bcdefgh */
1111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   b0 = (value >> 8) & 0xff;
1121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   if (value == ((b0 << 24) | (b0 << 8)))
1131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee       return (0x2 << 8) | b0; /* 0:010:a:bcdefgh */
1141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   /* Can we do it with rotation? */
1151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   zLeading = leadingZeros(value);
1161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   zTrailing = 32 - leadingZeros(~value & (value - 1));
1171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   /* A run of eight or fewer active bits? */
1181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   if ((zLeading + zTrailing) < 24)
1191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee       return -1;  /* No - bail */
1201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   /* left-justify the constant, discarding msb (known to be 1) */
1211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   value <<= zLeading + 1;
1221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   /* Create bcdefgh */
1231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   value >>= 25;
1241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   /* Put it all together */
1251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee   return value | ((0x8 + zLeading) << 7); /* [01000..11111]:bcdefgh */
1261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
1279bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee
1289bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee/*
1295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Load a immediate using a shortcut if possible; otherwise
1305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * grab from the per-translation literal pool.
1319bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee */
1325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadConstantValue(CompilationUnit *cUnit, int rDest, int value)
1339bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{
1345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    ArmLIR *res;
1355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int modImm;
1369bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee
1375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (FPREG(rDest)) {
1385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        return loadFPConstantValue(cUnit, rDest, value);
1391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
1409bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee
1415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    /* See if the value can be constructed cheaply */
1425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (LOWREG(rDest) && (value >= 0) && (value <= 255)) {
1435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        return newLIR2(cUnit, kThumbMovImm, rDest, value);
1441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
1455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    /* Check Modified immediate special cases */
1465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    modImm = modifiedImmediate(value);
1475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (modImm >= 0) {
1485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        res = newLIR2(cUnit, kThumb2MovImmShift, rDest, modImm);
1495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        return res;
1509bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee    }
1515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    modImm = modifiedImmediate(~value);
1525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (modImm >= 0) {
1535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        res = newLIR2(cUnit, kThumb2MvnImmShift, rDest, modImm);
1545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        return res;
155a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee    }
1565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    /* 16-bit immediate? */
1575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if ((value & 0xffff) == value) {
1585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        res = newLIR2(cUnit, kThumb2MovImm16, rDest, value);
1595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        return res;
160270c1d64a192341be842f46734054c692bac061eBill Buzbee    }
1615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    /* No shortcut - go ahead and use literal pool */
1625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    ArmLIR *dataTarget = scanLiteralPool(cUnit, value, 255);
1635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (dataTarget == NULL) {
1645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        dataTarget = addWordData(cUnit, value, false);
1655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
1665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    ArmLIR *loadPcRel = dvmCompilerNew(sizeof(ArmLIR), true);
1675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    loadPcRel->opCode = LOWREG(rDest) ? kThumbLdrPcRel : kThumb2LdrPcRel12;
1685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    loadPcRel->generic.target = (LIR *) dataTarget;
1695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    loadPcRel->operands[0] = rDest;
1705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    setupResourceMasks(loadPcRel);
1715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    res = loadPcRel;
1725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel);
173270c1d64a192341be842f46734054c692bac061eBill Buzbee
1745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    /*
1755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng     * To save space in the constant pool, we use the ADD_RRI8 instruction to
1765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng     * add up to 255 to an existing constant value.
1775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng     */
1785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (dataTarget->operands[0] != value) {
1795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        opRegImm(cUnit, kOpAdd, rDest, value - dataTarget->operands[0]);
1807ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee    }
1817ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee    return res;
1827ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee}
1837ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee
1845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/*
1855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Load an immediate value into a fixed or temp register.  Target
1865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * register is clobbered, and marked inUse.
1875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */
1885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value)
1899bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{
190c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee    if (dvmCompilerIsTemp(cUnit, rDest)) {
191c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        dvmCompilerClobber(cUnit, rDest);
192c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        dvmcompilerMarkInUse(cUnit, rDest);
1935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
1945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return loadConstantValue(cUnit, rDest, value);
1959bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee}
1969bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee
1971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opNone(CompilationUnit *cUnit, OpKind op)
1989bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{
1991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmOpCode opCode = kThumbBkpt;
2001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    switch (op) {
2011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpUncondBr:
2021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumbBUncond;
203270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
204270c1d64a192341be842f46734054c692bac061eBill Buzbee        default:
205270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(0);
206270c1d64a192341be842f46734054c692bac061eBill Buzbee    }
2071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return newLIR0(cUnit, opCode);
2089bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee}
2099bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee
2101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opCondBranch(CompilationUnit *cUnit, ArmConditionCode cc)
2119bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee{
2121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return newLIR2(cUnit, kThumbBCond, 0 /* offset to be patched */, cc);
2131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
2141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
2151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opImm(CompilationUnit *cUnit, OpKind op, int value)
2161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
2171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmOpCode opCode = kThumbBkpt;
2181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    switch (op) {
2191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpPush:
2201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = ((value & 0xff00) != 0) ? kThumb2Push : kThumbPush;
221270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
2221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpPop:
2231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = ((value & 0xff00) != 0) ? kThumb2Pop : kThumbPop;
224270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
225270c1d64a192341be842f46734054c692bac061eBill Buzbee        default:
226270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(0);
2279bc3df373ae6f4f7e6e97d554884d4e0dbad5494Bill Buzbee    }
2281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return newLIR1(cUnit, opCode, value);
229d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng}
230d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng
2311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc)
232d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng{
2331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmOpCode opCode = kThumbBkpt;
2341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    switch (op) {
2351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpBlx:
2361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumbBlxR;
2371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
2381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        default:
2391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            assert(0);
240d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng    }
2411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return newLIR1(cUnit, opCode, rDestSrc);
242d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng}
243d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng
2441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegShift(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
2451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                        int rSrc2, int shift)
246270c1d64a192341be842f46734054c692bac061eBill Buzbee{
247270c1d64a192341be842f46734054c692bac061eBill Buzbee    bool thumbForm = ((shift == 0) && LOWREG(rDestSrc1) && LOWREG(rSrc2));
2481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmOpCode opCode = kThumbBkpt;
249270c1d64a192341be842f46734054c692bac061eBill Buzbee    switch (op) {
2501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAdc:
2511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbAdcRR : kThumb2AdcRRR;
252270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
2531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAnd:
2541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbAndRR : kThumb2AndRRR;
255270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
2561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpBic:
2571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbBicRR : kThumb2BicRRR;
258270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
2591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpCmn:
260270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(shift == 0);
2611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbCmnRR : kThumb2CmnRR;
262270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
2631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpCmp:
264270c1d64a192341be842f46734054c692bac061eBill Buzbee            if (thumbForm)
2651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbCmpRR;
266270c1d64a192341be842f46734054c692bac061eBill Buzbee            else if ((shift == 0) && !LOWREG(rDestSrc1) && !LOWREG(rSrc2))
2671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbCmpHH;
268270c1d64a192341be842f46734054c692bac061eBill Buzbee            else if ((shift == 0) && LOWREG(rDestSrc1))
2691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbCmpLH;
270270c1d64a192341be842f46734054c692bac061eBill Buzbee            else if (shift == 0)
2711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbCmpHL;
272dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng            else
2731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumb2CmpRR;
274270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
2751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpXor:
2761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbEorRR : kThumb2EorRRR;
277270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
2781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpMov:
279270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(shift == 0);
280270c1d64a192341be842f46734054c692bac061eBill Buzbee            if (LOWREG(rDestSrc1) && LOWREG(rSrc2))
2811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbMovRR;
282270c1d64a192341be842f46734054c692bac061eBill Buzbee            else if (!LOWREG(rDestSrc1) && !LOWREG(rSrc2))
2831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbMovRR_H2H;
284270c1d64a192341be842f46734054c692bac061eBill Buzbee            else if (LOWREG(rDestSrc1))
2851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbMovRR_H2L;
286270c1d64a192341be842f46734054c692bac061eBill Buzbee            else
2871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbMovRR_L2H;
288270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
2891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpMul:
290270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(shift == 0);
2911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbMul : kThumb2MulRRR;
292270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
2931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpMvn:
2941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbMvn : kThumb2MnvRR;
295270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
2961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpNeg:
297270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(shift == 0);
2981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbNeg : kThumb2NegRR;
299270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
3001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpOr:
3011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbOrr : kThumb2OrrRRR;
302270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
3031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpSbc:
3041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbSbc : kThumb2SbcRRR;
305270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
3061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpTst:
3071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbTst : kThumb2TstRR;
308270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
3091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpLsl:
310270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(shift == 0);
3111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbLslRR : kThumb2LslRRR;
312270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
3131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpLsr:
314270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(shift == 0);
3151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbLsrRR : kThumb2LsrRRR;
316270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
3171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAsr:
318270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(shift == 0);
3191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbAsrRR : kThumb2AsrRRR;
320270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
3211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpRor:
322270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(shift == 0);
3231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbRorRR : kThumb2RorRRR;
324270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
3251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAdd:
3261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR;
327270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
3281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpSub:
3291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR;
330270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
3311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOp2Byte:
332270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(shift == 0);
3331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 8);
3341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOp2Short:
335270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(shift == 0);
3361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 16);
3371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOp2Char:
338270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(shift == 0);
3391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            return newLIR4(cUnit, kThumb2Ubfx, rDestSrc1, rSrc2, 0, 16);
340270c1d64a192341be842f46734054c692bac061eBill Buzbee        default:
341270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(0);
342270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
343270c1d64a192341be842f46734054c692bac061eBill Buzbee    }
344270c1d64a192341be842f46734054c692bac061eBill Buzbee    assert(opCode >= 0);
345270c1d64a192341be842f46734054c692bac061eBill Buzbee    if (EncodingMap[opCode].flags & IS_BINARY_OP)
346270c1d64a192341be842f46734054c692bac061eBill Buzbee        return newLIR2(cUnit, opCode, rDestSrc1, rSrc2);
347270c1d64a192341be842f46734054c692bac061eBill Buzbee    else if (EncodingMap[opCode].flags & IS_TERTIARY_OP) {
3481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        if (EncodingMap[opCode].fieldLoc[2].kind == kFmtShift)
349270c1d64a192341be842f46734054c692bac061eBill Buzbee            return newLIR3(cUnit, opCode, rDestSrc1, rSrc2, shift);
350270c1d64a192341be842f46734054c692bac061eBill Buzbee        else
351270c1d64a192341be842f46734054c692bac061eBill Buzbee            return newLIR3(cUnit, opCode, rDestSrc1, rDestSrc1, rSrc2);
352270c1d64a192341be842f46734054c692bac061eBill Buzbee    } else if (EncodingMap[opCode].flags & IS_QUAD_OP)
353270c1d64a192341be842f46734054c692bac061eBill Buzbee        return newLIR4(cUnit, opCode, rDestSrc1, rDestSrc1, rSrc2, shift);
354270c1d64a192341be842f46734054c692bac061eBill Buzbee    else {
355270c1d64a192341be842f46734054c692bac061eBill Buzbee        assert(0);
356270c1d64a192341be842f46734054c692bac061eBill Buzbee        return NULL;
357270c1d64a192341be842f46734054c692bac061eBill Buzbee    }
358270c1d64a192341be842f46734054c692bac061eBill Buzbee}
359270c1d64a192341be842f46734054c692bac061eBill Buzbee
360270c1d64a192341be842f46734054c692bac061eBill Buzbeestatic ArmLIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
361270c1d64a192341be842f46734054c692bac061eBill Buzbee                        int rSrc2)
362270c1d64a192341be842f46734054c692bac061eBill Buzbee{
363270c1d64a192341be842f46734054c692bac061eBill Buzbee    return opRegRegShift(cUnit, op, rDestSrc1, rSrc2, 0);
364270c1d64a192341be842f46734054c692bac061eBill Buzbee}
365270c1d64a192341be842f46734054c692bac061eBill Buzbee
3661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegRegShift(CompilationUnit *cUnit, OpKind op,
3671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                                int rDest, int rSrc1, int rSrc2, int shift)
3681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
3691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmOpCode opCode = kThumbBkpt;
3701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool thumbForm = (shift == 0) && LOWREG(rDest) && LOWREG(rSrc1) &&
3711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                      LOWREG(rSrc2);
3721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    switch (op) {
3731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAdd:
3741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR;
3751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
3761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpSub:
3771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR;
3781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
3791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAdc:
3801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2AdcRRR;
3811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
3821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAnd:
3831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2AndRRR;
3841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
3851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpBic:
3861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2BicRRR;
3871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
3881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpXor:
3891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2EorRRR;
3901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
3911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpMul:
3921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            assert(shift == 0);
3931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2MulRRR;
3941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
3951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpOr:
3961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2OrrRRR;
3971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
3981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpSbc:
3991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2SbcRRR;
4001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
4011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpLsl:
4021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            assert(shift == 0);
4031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2LslRRR;
4041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
4051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpLsr:
4061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            assert(shift == 0);
4071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2LsrRRR;
4081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
4091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAsr:
4101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            assert(shift == 0);
4111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2AsrRRR;
4121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
4131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpRor:
4141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            assert(shift == 0);
4151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2RorRRR;
4161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
4171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        default:
4181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            assert(0);
4191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
4201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
4211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    assert(opCode >= 0);
4221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (EncodingMap[opCode].flags & IS_QUAD_OP)
4231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        return newLIR4(cUnit, opCode, rDest, rSrc1, rSrc2, shift);
4241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    else {
4251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        assert(EncodingMap[opCode].flags & IS_TERTIARY_OP);
4261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        return newLIR3(cUnit, opCode, rDest, rSrc1, rSrc2);
4271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
4281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
4291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
4301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegReg(CompilationUnit *cUnit, OpKind op, int rDest,
4311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                           int rSrc1, int rSrc2)
4321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
4331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return opRegRegRegShift(cUnit, op, rDest, rSrc1, rSrc2, 0);
4341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
4351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
4361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest,
4371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                           int rSrc1, int value)
4381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
4391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmLIR *res;
4401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool neg = (value < 0);
4411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    int absValue = (neg) ? -value : value;
4421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmOpCode opCode = kThumbBkpt;
4431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmOpCode altOpCode = kThumbBkpt;
4441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool allLowRegs = (LOWREG(rDest) && LOWREG(rSrc1));
4451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    int modImm = modifiedImmediate(value);
4461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    int modImmNeg = modifiedImmediate(-value);
4471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
4481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    switch(op) {
4491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpLsl:
4501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (allLowRegs)
4511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return newLIR3(cUnit, kThumbLslRRI5, rDest, rSrc1, value);
4521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            else
4531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return newLIR3(cUnit, kThumb2LslRRI5, rDest, rSrc1, value);
4541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpLsr:
4551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (allLowRegs)
4561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return newLIR3(cUnit, kThumbLsrRRI5, rDest, rSrc1, value);
4571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            else
4581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return newLIR3(cUnit, kThumb2LsrRRI5, rDest, rSrc1, value);
4591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAsr:
4601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (allLowRegs)
4611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return newLIR3(cUnit, kThumbAsrRRI5, rDest, rSrc1, value);
4621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            else
4631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return newLIR3(cUnit, kThumb2AsrRRI5, rDest, rSrc1, value);
4641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpRor:
4651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            return newLIR3(cUnit, kThumb2RorRRI5, rDest, rSrc1, value);
4661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAdd:
4671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (LOWREG(rDest) && (rSrc1 == 13) &&
4681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                (value <= 1020) && ((value & 0x3)==0)) {
4691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return newLIR3(cUnit, kThumbAddSpRel, rDest, rSrc1,
4701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                               value >> 2);
4711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else if (LOWREG(rDest) && (rSrc1 == rpc) &&
4721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                       (value <= 1020) && ((value & 0x3)==0)) {
4731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return newLIR3(cUnit, kThumbAddPcRel, rDest, rSrc1,
4741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                               value >> 2);
4751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
4761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2AddRRI8;
4771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            altOpCode = kThumb2AddRRR;
4781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            // Note: intentional fallthrough
4791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpSub:
4801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (allLowRegs && ((absValue & 0x7) == absValue)) {
4811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                if (op == kOpAdd)
4821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                    opCode = (neg) ? kThumbSubRRI3 : kThumbAddRRI3;
4831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                else
4841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                    opCode = (neg) ? kThumbAddRRI3 : kThumbSubRRI3;
4851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return newLIR3(cUnit, opCode, rDest, rSrc1, absValue);
4861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else if ((absValue & 0xff) == absValue) {
4871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                if (op == kOpAdd)
4881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                    opCode = (neg) ? kThumb2SubRRI12 : kThumb2AddRRI12;
4891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                else
4901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                    opCode = (neg) ? kThumb2AddRRI12 : kThumb2SubRRI12;
4911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return newLIR3(cUnit, opCode, rDest, rSrc1, absValue);
4921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
4931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (modImmNeg >= 0) {
4941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                op = (op == kOpAdd) ? kOpSub : kOpAdd;
4951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                modImm = modImmNeg;
4961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
4971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (op == kOpSub) {
4981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumb2SubRRI8;
4991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                altOpCode = kThumb2SubRRR;
5001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
5011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
5021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAdc:
5031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2AdcRRI8;
5041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            altOpCode = kThumb2AdcRRR;
5051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
5061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpSbc:
5071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2SbcRRI8;
5081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            altOpCode = kThumb2SbcRRR;
5091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
5101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpOr:
5111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2OrrRRI8;
5121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            altOpCode = kThumb2OrrRRR;
5131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
5141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAnd:
5151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2AndRRI8;
5161465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            altOpCode = kThumb2AndRRR;
5171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
5181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpXor:
5191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2EorRRI8;
5201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            altOpCode = kThumb2EorRRR;
5211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
5221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpMul:
5231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            //TUNING: power of 2, shift & add
5241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            modImm = -1;
5251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            altOpCode = kThumb2MulRRR;
5261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            break;
5271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpCmp: {
5281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            int modImm = modifiedImmediate(value);
5291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            ArmLIR *res;
5301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (modImm >= 0) {
5311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                res = newLIR2(cUnit, kThumb2CmpRI8, rSrc1, modImm);
5321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else {
533c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                int rTmp = dvmCompilerAllocTemp(cUnit);
5341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                res = loadConstant(cUnit, rTmp, value);
5351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opRegReg(cUnit, kOpCmp, rSrc1, rTmp);
536c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                dvmCompilerFreeTemp(cUnit, rTmp);
5371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
5381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            return res;
5391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        }
5401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        default:
5411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            assert(0);
5421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
5431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
5441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (modImm >= 0) {
5451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        return newLIR3(cUnit, opCode, rDest, rSrc1, modImm);
5461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    } else {
547c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        int rScratch = dvmCompilerAllocTemp(cUnit);
5481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        loadConstant(cUnit, rScratch, value);
5491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        if (EncodingMap[altOpCode].flags & IS_QUAD_OP)
5501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            res = newLIR4(cUnit, altOpCode, rDest, rSrc1, rScratch, 0);
5511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        else
5521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            res = newLIR3(cUnit, altOpCode, rDest, rSrc1, rScratch);
553c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        dvmCompilerFreeTemp(cUnit, rScratch);
5541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        return res;
5551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
5561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
5571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
558270c1d64a192341be842f46734054c692bac061eBill Buzbee/* Handle Thumb-only variants here - otherwise punt to opRegRegImm */
559270c1d64a192341be842f46734054c692bac061eBill Buzbeestatic ArmLIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
5601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                        int value)
561270c1d64a192341be842f46734054c692bac061eBill Buzbee{
562270c1d64a192341be842f46734054c692bac061eBill Buzbee    ArmLIR *res;
563270c1d64a192341be842f46734054c692bac061eBill Buzbee    bool neg = (value < 0);
564270c1d64a192341be842f46734054c692bac061eBill Buzbee    int absValue = (neg) ? -value : value;
565270c1d64a192341be842f46734054c692bac061eBill Buzbee    bool shortForm = (((absValue & 0xff) == absValue) && LOWREG(rDestSrc1));
5661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmOpCode opCode = kThumbBkpt;
567270c1d64a192341be842f46734054c692bac061eBill Buzbee    switch (op) {
5681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpAdd:
569270c1d64a192341be842f46734054c692bac061eBill Buzbee            if ( !neg && (rDestSrc1 == 13) && (value <= 508)) { /* sp */
570270c1d64a192341be842f46734054c692bac061eBill Buzbee                assert((value & 0x3) == 0);
5711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return newLIR1(cUnit, kThumbAddSpI7, value >> 2);
572270c1d64a192341be842f46734054c692bac061eBill Buzbee            } else if (shortForm) {
5731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = (neg) ? kThumbSubRI8 : kThumbAddRI8;
574270c1d64a192341be842f46734054c692bac061eBill Buzbee            }
575270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
5761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpSub:
577270c1d64a192341be842f46734054c692bac061eBill Buzbee            if (!neg && (rDestSrc1 == 13) && (value <= 508)) { /* sp */
578270c1d64a192341be842f46734054c692bac061eBill Buzbee                assert((value & 0x3) == 0);
5791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return newLIR1(cUnit, kThumbSubSpI7, value >> 2);
580270c1d64a192341be842f46734054c692bac061eBill Buzbee            } else if (shortForm) {
5811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = (neg) ? kThumbAddRI8 : kThumbSubRI8;
582270c1d64a192341be842f46734054c692bac061eBill Buzbee            }
583270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
5841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kOpCmp:
585270c1d64a192341be842f46734054c692bac061eBill Buzbee            if (LOWREG(rDestSrc1) && shortForm)
5861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = (shortForm) ?  kThumbCmpRI8 : kThumbCmpRR;
587270c1d64a192341be842f46734054c692bac061eBill Buzbee            else if (LOWREG(rDestSrc1))
5881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbCmpRR;
589270c1d64a192341be842f46734054c692bac061eBill Buzbee            else {
590270c1d64a192341be842f46734054c692bac061eBill Buzbee                shortForm = false;
5911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbCmpHL;
592270c1d64a192341be842f46734054c692bac061eBill Buzbee            }
593270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
594270c1d64a192341be842f46734054c692bac061eBill Buzbee        default:
595270c1d64a192341be842f46734054c692bac061eBill Buzbee            /* Punt to opRegRegImm - if bad case catch it there */
596270c1d64a192341be842f46734054c692bac061eBill Buzbee            shortForm = false;
597270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
598270c1d64a192341be842f46734054c692bac061eBill Buzbee    }
599270c1d64a192341be842f46734054c692bac061eBill Buzbee    if (shortForm)
600270c1d64a192341be842f46734054c692bac061eBill Buzbee        return newLIR2(cUnit, opCode, rDestSrc1, absValue);
6011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    else {
6021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value);
6031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
604270c1d64a192341be842f46734054c692bac061eBill Buzbee}
605270c1d64a192341be842f46734054c692bac061eBill Buzbee
6061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/*
6075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Determine whether value can be encoded as a Thumb2 floating point
6085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * immediate.  If not, return -1.  If so return encoded 8-bit value.
6091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee */
6105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeImmDoubleHigh(int value)
6111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
6125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int res;
6135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int bitA =    (value & 0x80000000) >> 31;
6145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int notBitB = (value & 0x40000000) >> 30;
6155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int bitB =    (value & 0x20000000) >> 29;
6165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int bSmear =  (value & 0x3fc00000) >> 22;
6175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int slice =   (value & 0x003f0000) >> 16;
6185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int zeroes =  (value & 0x0000ffff);
6195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (zeroes != 0)
6205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        return -1;
6215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (bitB) {
6225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        if ((notBitB != 0) || (bSmear != 0x1f))
6235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            return -1;
6241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    } else {
6255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        if ((notBitB != 1) || (bSmear != 0x0))
6265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            return -1;
6271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
6285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    res = (bitA << 7) | (bitB << 6) | slice;
6295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return res;
6305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng}
6311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
6325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeImmDouble(int valLo, int valHi)
6335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{
6345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int res = -1;
6355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (valLo == 0)
6365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        res = encodeImmDoubleHigh(valHi);
6375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return res;
6385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng}
6391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
6405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *loadConstantValueWide(CompilationUnit *cUnit, int rDestLo,
6415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                                     int rDestHi, int valLo, int valHi)
6425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{
6435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    int encodedImm = encodeImmDouble(valLo, valHi);
6445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    ArmLIR *res;
6455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (FPREG(rDestLo) && (encodedImm >= 0)) {
6465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        res = newLIR2(cUnit, kThumb2Vmovd_IMM8, S2D(rDestLo, rDestHi),
6475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                      encodedImm);
6481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    } else {
6495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        res = loadConstantValue(cUnit, rDestLo, valLo);
6505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        loadConstantValue(cUnit, rDestHi, valHi);
6511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
6525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return res;
6531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
6541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
6555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic int encodeShift(int code, int amount) {
6565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return ((amount & 0x1f) << 2) | code;
6571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
6581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
6591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase,
6601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                               int rIndex, int rDest, int scale, OpSize size)
6611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
6621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rDest);
6639e45c0b968d63ea38353c99252d233879c2efdafjeffhao    ArmLIR *load;
6641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmOpCode opCode = kThumbBkpt;
6651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool thumbForm = (allLowRegs && (scale == 0));
6661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    int regPtr;
6671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
6681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (FPREG(rDest)) {
6691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        assert(SINGLEREG(rDest));
6701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        assert((size == kWord) || (size == kSingle));
6711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        opCode = kThumb2Vldrs;
6721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        size = kSingle;
6731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    } else {
6741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        if (size == kSingle)
6751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            size = kWord;
6761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
6771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
6781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    switch (size) {
6791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kSingle:
680c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee            regPtr = dvmCompilerAllocTemp(cUnit);
6811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (scale) {
6821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex,
6831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                        encodeShift(kArmLsl, scale));
6841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else {
6851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex);
6861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
6879e45c0b968d63ea38353c99252d233879c2efdafjeffhao            load = newLIR3(cUnit, opCode, rDest, regPtr, 0);
6889e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION)
6899e45c0b968d63ea38353c99252d233879c2efdafjeffhao            if (cUnit->heapMemOp)
6909e45c0b968d63ea38353c99252d233879c2efdafjeffhao                load->branchInsertSV = true;
6919e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif
6929e45c0b968d63ea38353c99252d233879c2efdafjeffhao            return load;
6931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kWord:
6941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbLdrRRR : kThumb2LdrRRR;
695270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
6961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kUnsignedHalf:
6971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbLdrhRRR : kThumb2LdrhRRR;
698270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
6991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kSignedHalf:
7001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbLdrshRRR : kThumb2LdrshRRR;
701270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
7021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kUnsignedByte:
7031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbLdrbRRR : kThumb2LdrbRRR;
704270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
7051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kSignedByte:
7061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbLdrsbRRR : kThumb2LdrsbRRR;
707270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
7081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        default:
7091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            assert(0);
7101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
7111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (thumbForm)
7129e45c0b968d63ea38353c99252d233879c2efdafjeffhao        load = newLIR3(cUnit, opCode, rDest, rBase, rIndex);
7131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    else
7149e45c0b968d63ea38353c99252d233879c2efdafjeffhao        load = newLIR4(cUnit, opCode, rDest, rBase, rIndex, scale);
7159e45c0b968d63ea38353c99252d233879c2efdafjeffhao
7169e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION)
7179e45c0b968d63ea38353c99252d233879c2efdafjeffhao    if (cUnit->heapMemOp)
7189e45c0b968d63ea38353c99252d233879c2efdafjeffhao        load->branchInsertSV = true;
7199e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif
7209e45c0b968d63ea38353c99252d233879c2efdafjeffhao    return load;
7211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
7221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
7231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase,
7241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                                int rIndex, int rSrc, int scale, OpSize size)
7251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
7261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rSrc);
7279e45c0b968d63ea38353c99252d233879c2efdafjeffhao    ArmLIR *store;
7281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmOpCode opCode = kThumbBkpt;
7291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool thumbForm = (allLowRegs && (scale == 0));
7301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    int regPtr;
7311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
7321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (FPREG(rSrc)) {
7331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        assert(SINGLEREG(rSrc));
7341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        assert((size == kWord) || (size == kSingle));
7351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        opCode = kThumb2Vstrs;
7361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        size = kSingle;
7371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    } else {
7381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        if (size == kSingle)
7391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            size = kWord;
7401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
7411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
7421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    switch (size) {
7431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kSingle:
744c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee            regPtr = dvmCompilerAllocTemp(cUnit);
7451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (scale) {
7461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex,
7471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                        encodeShift(kArmLsl, scale));
7481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else {
7491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex);
7501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
7519e45c0b968d63ea38353c99252d233879c2efdafjeffhao            store = newLIR3(cUnit, opCode, rSrc, regPtr, 0);
7529e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION)
7539e45c0b968d63ea38353c99252d233879c2efdafjeffhao            if (cUnit->heapMemOp)
7549e45c0b968d63ea38353c99252d233879c2efdafjeffhao                store->branchInsertSV = true;
7559e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif
7569e45c0b968d63ea38353c99252d233879c2efdafjeffhao            return store;
7571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kWord:
7581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbStrRRR : kThumb2StrRRR;
759270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
7601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kUnsignedHalf:
7611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kSignedHalf:
7621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbStrhRRR : kThumb2StrhRRR;
763270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
7641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kUnsignedByte:
7651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kSignedByte:
7661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = (thumbForm) ? kThumbStrbRRR : kThumb2StrbRRR;
767270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
7681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        default:
7691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            assert(0);
7701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
7711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (thumbForm)
7729e45c0b968d63ea38353c99252d233879c2efdafjeffhao        store = newLIR3(cUnit, opCode, rSrc, rBase, rIndex);
7731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    else
7749e45c0b968d63ea38353c99252d233879c2efdafjeffhao        store = newLIR4(cUnit, opCode, rSrc, rBase, rIndex, scale);
7759e45c0b968d63ea38353c99252d233879c2efdafjeffhao
7769e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION)
7779e45c0b968d63ea38353c99252d233879c2efdafjeffhao    if (cUnit->heapMemOp)
7789e45c0b968d63ea38353c99252d233879c2efdafjeffhao        store->branchInsertSV = true;
7799e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif
7809e45c0b968d63ea38353c99252d233879c2efdafjeffhao    return store;
7811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
7821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
7831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/*
7841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * Load value from base + displacement.  Optionally perform null check
7851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * on base (which must have an associated sReg and MIR).  If not
7861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * performing null check, incoming MIR can be null.
7871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee */
7881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase,
7891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                                int displacement, int rDest, int rDestHi,
7905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                                OpSize size, int sReg)
7911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
7921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmLIR *res, *load;
7931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmOpCode opCode = kThumbBkpt;
7941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool shortForm = false;
7951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool thumb2Form = (displacement < 4092 && displacement >= 0);
7961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    int shortMax = 128;
7971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool allLowRegs = (LOWREG(rBase) && LOWREG(rDest));
7981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    int encodedDisp = displacement;
7991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
8001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    switch (size) {
8011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kDouble:
8021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kLong:
8031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (FPREG(rDest)) {
8041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                if (SINGLEREG(rDest)) {
8051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                    assert(FPREG(rDestHi));
8061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                    rDest = S2D(rDest, rDestHi);
8071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                }
8081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumb2Vldrd;
8091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                if (displacement <= 1020) {
8101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                    shortForm = true;
8111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                    encodedDisp >>= 2;
8121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                }
8131465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                break;
8141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else {
8151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                res = loadBaseDispBody(cUnit, mir, rBase, displacement, rDest,
8165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                                       -1, kWord, sReg);
8171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                loadBaseDispBody(cUnit, NULL, rBase, displacement + 4, rDestHi,
8185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                                 -1, kWord, INVALID_SREG);
8191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return res;
8201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
8211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kSingle:
8221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kWord:
8231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (FPREG(rDest)) {
8241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumb2Vldrs;
8251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                if (displacement <= 1020) {
8261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                    shortForm = true;
8271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                    encodedDisp >>= 2;
8281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                }
8291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                break;
8301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
8311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (LOWREG(rDest) && (rBase == rpc) &&
8321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                (displacement <= 1020) && (displacement >= 0)) {
8331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
8341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                encodedDisp >>= 2;
8351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbLdrPcRel;
8361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else if (LOWREG(rDest) && (rBase == r13) &&
8371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                      (displacement <= 1020) && (displacement >= 0)) {
8381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
8391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                encodedDisp >>= 2;
8401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbLdrSpRel;
8411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else if (allLowRegs && displacement < 128 && displacement >= 0) {
8421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                assert((displacement & 0x3) == 0);
8431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
8441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                encodedDisp >>= 2;
8451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbLdrRRI5;
8461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else if (thumb2Form) {
8471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
8481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumb2LdrRRI12;
8491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
850270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
8511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kUnsignedHalf:
8521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (allLowRegs && displacement < 64 && displacement >= 0) {
8531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                assert((displacement & 0x1) == 0);
8541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
8551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                encodedDisp >>= 1;
8561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbLdrhRRI5;
8571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else if (displacement < 4092 && displacement >= 0) {
8581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
8591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumb2LdrhRRI12;
8601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
861270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
8621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kSignedHalf:
8631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (thumb2Form) {
8641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
8651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumb2LdrshRRI12;
8661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
867270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
8681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kUnsignedByte:
8691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (allLowRegs && displacement < 32 && displacement >= 0) {
8701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
8711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbLdrbRRI5;
8721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else if (thumb2Form) {
8731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
8741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumb2LdrbRRI12;
8751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
876270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
8771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kSignedByte:
8781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (thumb2Form) {
8791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
8801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumb2LdrsbRRI12;
8811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
882270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
883270c1d64a192341be842f46734054c692bac061eBill Buzbee        default:
884270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(0);
885270c1d64a192341be842f46734054c692bac061eBill Buzbee    }
8865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng
8871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (shortForm) {
8881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        load = res = newLIR3(cUnit, opCode, rDest, rBase, encodedDisp);
8891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    } else {
890c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        int regOffset = dvmCompilerAllocTemp(cUnit);
8911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        res = loadConstant(cUnit, regOffset, encodedDisp);
8921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        load = loadBaseIndexed(cUnit, rBase, regOffset, rDest, 0, size);
893c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        dvmCompilerFreeTemp(cUnit, regOffset);
8941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
8951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
8961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (rBase == rFP) {
8971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        annotateDalvikRegAccess(load, displacement >> 2, true /* isLoad */);
898270c1d64a192341be842f46734054c692bac061eBill Buzbee    }
8999e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION)
9009e45c0b968d63ea38353c99252d233879c2efdafjeffhao    if (cUnit->heapMemOp)
9019e45c0b968d63ea38353c99252d233879c2efdafjeffhao        load->branchInsertSV = true;
9029e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif
9035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return res;
904270c1d64a192341be842f46734054c692bac061eBill Buzbee}
905270c1d64a192341be842f46734054c692bac061eBill Buzbee
9061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase,
9071465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                            int displacement, int rDest, OpSize size,
9085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                            int sReg)
909270c1d64a192341be842f46734054c692bac061eBill Buzbee{
9101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1,
9115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                            size, sReg);
912270c1d64a192341be842f46734054c692bac061eBill Buzbee}
913270c1d64a192341be842f46734054c692bac061eBill Buzbee
9145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic  ArmLIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase,
915c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                                 int displacement, int rDestLo, int rDestHi,
916c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                                 int sReg)
917270c1d64a192341be842f46734054c692bac061eBill Buzbee{
9181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi,
9195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                            kLong, sReg);
9201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
921270c1d64a192341be842f46734054c692bac061eBill Buzbee
9221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
9231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase,
924c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                                 int displacement, int rSrc, int rSrcHi,
925c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                                 OpSize size)
9261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
9271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmLIR *res, *store;
9281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmOpCode opCode = kThumbBkpt;
9291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool shortForm = false;
9301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool thumb2Form = (displacement < 4092 && displacement >= 0);
9311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    int shortMax = 128;
9321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bool allLowRegs = (LOWREG(rBase) && LOWREG(rSrc));
9331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    int encodedDisp = displacement;
9341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
9351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    switch (size) {
9361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kLong:
9371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kDouble:
9381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (!FPREG(rSrc)) {
9391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                res = storeBaseDispBody(cUnit, rBase, displacement, rSrc,
9401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                                        -1, kWord);
9411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                storeBaseDispBody(cUnit, rBase, displacement + 4, rSrcHi,
9421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                                  -1, kWord);
9431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                return res;
944270c1d64a192341be842f46734054c692bac061eBill Buzbee            }
9451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (SINGLEREG(rSrc)) {
9461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                assert(FPREG(rSrcHi));
9471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                rSrc = S2D(rSrc, rSrcHi);
948270c1d64a192341be842f46734054c692bac061eBill Buzbee            }
9491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opCode = kThumb2Vstrd;
9501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (displacement <= 1020) {
9511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
9521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                encodedDisp >>= 2;
953270c1d64a192341be842f46734054c692bac061eBill Buzbee            }
954270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
9551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kSingle:
9561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kWord:
9571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (FPREG(rSrc)) {
9581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                assert(SINGLEREG(rSrc));
9591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumb2Vstrs;
9601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                if (displacement <= 1020) {
9611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                    shortForm = true;
9621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                    encodedDisp >>= 2;
9631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                }
964270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
9651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
9661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (allLowRegs && displacement < 128 && displacement >= 0) {
9671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                assert((displacement & 0x3) == 0);
9681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
9691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                encodedDisp >>= 2;
9701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbStrRRI5;
9711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else if (thumb2Form) {
9721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
9731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumb2StrRRI12;
9741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
975270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
9761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kUnsignedHalf:
9771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kSignedHalf:
9781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (allLowRegs && displacement < 64 && displacement >= 0) {
9791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                assert((displacement & 0x1) == 0);
9801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
9811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                encodedDisp >>= 1;
9821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbStrhRRI5;
9831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else if (thumb2Form) {
9841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
9851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumb2StrhRRI12;
9861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
987270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
9881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kUnsignedByte:
9891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        case kSignedByte:
9901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            if (allLowRegs && displacement < 32 && displacement >= 0) {
9911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
9921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                opCode = kThumbStrbRRI5;
9931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            } else if (thumb2Form) {
9941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                shortForm = true;
995964a7b06a9134947b5985c7f712d18d57ed665d2Bill Buzbee                opCode = kThumb2StrbRRI12;
9961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            }
997270c1d64a192341be842f46734054c692bac061eBill Buzbee            break;
998270c1d64a192341be842f46734054c692bac061eBill Buzbee        default:
999270c1d64a192341be842f46734054c692bac061eBill Buzbee            assert(0);
1000270c1d64a192341be842f46734054c692bac061eBill Buzbee    }
10011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (shortForm) {
10021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        store = res = newLIR3(cUnit, opCode, rSrc, rBase, encodedDisp);
10031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    } else {
1004c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        int rScratch = dvmCompilerAllocTemp(cUnit);
10051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        res = loadConstant(cUnit, rScratch, encodedDisp);
10061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        store = storeBaseIndexed(cUnit, rBase, rScratch, rSrc, 0, size);
1007c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee        dvmCompilerFreeTemp(cUnit, rScratch);
10081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
10091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
10101465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (rBase == rFP) {
10111465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        annotateDalvikRegAccess(store, displacement >> 2, false /* isLoad */);
10121465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
10139e45c0b968d63ea38353c99252d233879c2efdafjeffhao#if defined(WITH_SELF_VERIFICATION)
10149e45c0b968d63ea38353c99252d233879c2efdafjeffhao    if (cUnit->heapMemOp)
10159e45c0b968d63ea38353c99252d233879c2efdafjeffhao        store->branchInsertSV = true;
10169e45c0b968d63ea38353c99252d233879c2efdafjeffhao#endif
10171465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return res;
10181465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
10191465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
10201465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDisp(CompilationUnit *cUnit, int rBase,
10211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                             int displacement, int rSrc, OpSize size)
10221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
10231465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size);
10241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
10251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
10261465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase,
10271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                                 int displacement, int rSrcLo, int rSrcHi)
10281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
10291465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong);
10301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
10311465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
10321465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask)
10331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
10341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmLIR *res;
10351465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    genBarrier(cUnit);
10361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (LOWREG(rBase) && ((rMask & 0xff)==rMask)) {
10371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        res = newLIR2(cUnit, kThumbLdmia, rBase, rMask);
10381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    } else {
10391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        res = newLIR2(cUnit, kThumb2Ldmia, rBase, rMask);
10401465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
10411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    genBarrier(cUnit);
10421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return res;
10431465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
10441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
10451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask)
10461465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
10471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmLIR *res;
10481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    genBarrier(cUnit);
10491465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (LOWREG(rBase) && ((rMask & 0xff)==rMask)) {
10501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        res = newLIR2(cUnit, kThumbStmia, rBase, rMask);
10511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    } else {
10521465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        res = newLIR2(cUnit, kThumb2Stmia, rBase, rMask);
10531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
10541465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    genBarrier(cUnit);
10551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return res;
10561465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
10571465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
10581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
10591465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
10601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    storeBaseDispWide(cUnit, base, 0, lowReg, highReg);
10611465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
10621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
10631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
10641465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee{
10655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG);
10661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee}
10671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
10681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
10691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/*
10701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * Perform a "reg cmp imm" operation and jump to the PCR region if condition
10711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee * satisfies.
1072a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee */
10731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbeestatic ArmLIR *genRegImmCheck(CompilationUnit *cUnit,
1074c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                              ArmConditionCode cond, int reg,
1075c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                              int checkValue, int dOffset,
1076c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee                              ArmLIR *pcrLabel)
1077a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee{
10781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ArmLIR *branch;
10791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    int modImm;
10801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    /*
10811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * TODO: re-enable usage of kThumb2Cbz & kThumb2Cbnz once assembler is
10821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * enhanced to allow us to replace code patterns when instructions don't
10831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * reach.  Currently, CB[N]Z is causing too many assembler aborts.
10841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * What we want to do is emit the short forms, and then replace them with
10851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * longer versions when needed.
10861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     */
1087a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee
10881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    if (0 && (LOWREG(reg)) && (checkValue == 0) &&
10891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee       ((cond == kArmCondEq) || (cond == kArmCondNe))) {
10901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        branch = newLIR2(cUnit,
10911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                         (cond == kArmCondEq) ? kThumb2Cbz : kThumb2Cbnz,
10921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee                         reg, 0);
10931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    } else {
10941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        modImm = modifiedImmediate(checkValue);
10951465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        if (LOWREG(reg) && ((checkValue & 0xff) == checkValue)) {
10961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            newLIR2(cUnit, kThumbCmpRI8, reg, checkValue);
10971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        } else if (modImm >= 0) {
10981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            newLIR2(cUnit, kThumb2CmpRI8, reg, modImm);
10991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        } else {
1100c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee            int tReg = dvmCompilerAllocTemp(cUnit);
11011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            loadConstant(cUnit, tReg, checkValue);
11021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee            opRegReg(cUnit, kOpCmp, reg, tReg);
11031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        }
11041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee        branch = newLIR2(cUnit, kThumbBCond, 0, cond);
11051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    }
11061465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    return genCheckCommon(cUnit, dOffset, branch, pcrLabel);
1107a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee}
1108a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee
11095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
1110270c1d64a192341be842f46734054c692bac061eBill Buzbee{
11115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    ArmLIR* res = dvmCompilerNew(sizeof(ArmLIR), true);
11125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    res->operands[0] = rDest;
11135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    res->operands[1] = rSrc;
11145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (rDest == rSrc) {
11155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        res->isNop = true;
11165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    } else {
11175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        assert(DOUBLEREG(rDest) == DOUBLEREG(rSrc));
11185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        if (DOUBLEREG(rDest)) {
11195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            res->opCode = kThumb2Vmovd;
11205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        } else {
11215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            if (SINGLEREG(rDest)) {
11225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                res->opCode = SINGLEREG(rSrc) ? kThumb2Vmovs : kThumb2Fmsr;
11235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            } else {
11245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                assert(SINGLEREG(rSrc));
11255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                res->opCode = kThumb2Fmrs;
11265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            }
11275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        }
11285d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        res->operands[0] = rDest;
11295d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        res->operands[1] = rSrc;
11305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
11315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    setupResourceMasks(res);
11325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return res;
1133270c1d64a192341be842f46734054c692bac061eBill Buzbee}
1134270c1d64a192341be842f46734054c692bac061eBill Buzbee
11355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
1136270c1d64a192341be842f46734054c692bac061eBill Buzbee{
11375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    ArmLIR* res;
11385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    ArmOpCode opCode;
11395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (FPREG(rDest) || FPREG(rSrc))
11405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        return fpRegCopy(cUnit, rDest, rSrc);
11415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    res = dvmCompilerNew(sizeof(ArmLIR), true);
11425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (LOWREG(rDest) && LOWREG(rSrc))
11435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        opCode = kThumbMovRR;
11445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    else if (!LOWREG(rDest) && !LOWREG(rSrc))
11455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng         opCode = kThumbMovRR_H2H;
11465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    else if (LOWREG(rDest))
11475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng         opCode = kThumbMovRR_H2L;
11485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    else
11495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng         opCode = kThumbMovRR_L2H;
1150270c1d64a192341be842f46734054c692bac061eBill Buzbee
11515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    res->operands[0] = rDest;
11525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    res->operands[1] = rSrc;
11535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    res->opCode = opCode;
11545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    setupResourceMasks(res);
11555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (rDest == rSrc) {
11565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        res->isNop = true;
11575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
11585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return res;
1159270c1d64a192341be842f46734054c692bac061eBill Buzbee}
1160270c1d64a192341be842f46734054c692bac061eBill Buzbee
11615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic ArmLIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
1162270c1d64a192341be842f46734054c692bac061eBill Buzbee{
11635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    ArmLIR *res = genRegCopyNoInsert(cUnit, rDest, rSrc);
11645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    dvmCompilerAppendLIR(cUnit, (LIR*)res);
11655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    return res;
1166270c1d64a192341be842f46734054c692bac061eBill Buzbee}
1167270c1d64a192341be842f46734054c692bac061eBill Buzbee
11685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
11695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                           int srcLo, int srcHi)
1170270c1d64a192341be842f46734054c692bac061eBill Buzbee{
11715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    bool destFP = FPREG(destLo) && FPREG(destHi);
11725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    bool srcFP = FPREG(srcLo) && FPREG(srcHi);
11735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    assert(FPREG(srcLo) == FPREG(srcHi));
11745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    assert(FPREG(destLo) == FPREG(destHi));
11755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    if (destFP) {
11765d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        if (srcFP) {
11775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            genRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi));
11785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        } else {
11795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            newLIR3(cUnit, kThumb2Fmdrr, S2D(destLo, destHi), srcLo, srcHi);
11805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        }
11815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    } else {
11825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        if (srcFP) {
11835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            newLIR3(cUnit, kThumb2Fmrrd, destLo, destHi, S2D(srcLo, srcHi));
11845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        } else {
11855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            // Handle overlap
11865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            if (srcHi == destLo) {
11875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                genRegCopy(cUnit, destHi, srcHi);
11885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                genRegCopy(cUnit, destLo, srcLo);
11895d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            } else {
11905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                genRegCopy(cUnit, destLo, srcLo);
11915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng                genRegCopy(cUnit, destHi, srcHi);
11925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng            }
11935d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng        }
11945d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng    }
1195270c1d64a192341be842f46734054c692bac061eBill Buzbee}
1196