167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Copyright (C) 2011 The Android Open Source Project 367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Licensed under the Apache License, Version 2.0 (the "License"); 567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * you may not use this file except in compliance with the License. 667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * You may obtain a copy of the License at 767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * http://www.apache.org/licenses/LICENSE-2.0 967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 1067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Unless required by applicable law or agreed to in writing, software 1167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * distributed under the License is distributed on an "AS IS" BASIS, 1267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * See the License for the specific language governing permissions and 1467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * limitations under the License. 1567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 1667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 171bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee#include "arm_lir.h" 1802031b185b4653e6c72e21f7a51238b903f6d638buzbee#include "codegen_arm.h" 197940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir-inl.h" 201bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 2111d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughesnamespace art { 2211d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 23b046e16d8b8da318d6055f9308950131f1255e08buzbee/* This file contains codegen for the Thumb ISA. */ 2467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 252ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromstatic int EncodeImmSingle(int value) { 26a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int res; 27fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int bit_a = (value & 0x80000000) >> 31; 28fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int not_bit_b = (value & 0x40000000) >> 30; 29fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int bit_b = (value & 0x20000000) >> 29; 30fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int b_smear = (value & 0x3e000000) >> 25; 31a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int slice = (value & 0x01f80000) >> 19; 32a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int zeroes = (value & 0x0007ffff); 33a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (zeroes != 0) 34a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return -1; 35fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (bit_b) { 36fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if ((not_bit_b != 0) || (b_smear != 0x1f)) 37a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return -1; 38a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 39fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if ((not_bit_b != 1) || (b_smear != 0x0)) 40a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return -1; 41a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 42fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res = (bit_a << 7) | (bit_b << 6) | slice; 43a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return res; 4467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 4567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 464ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee/* 474ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee * Determine whether value can be encoded as a Thumb2 floating point 484ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee * immediate. If not, return -1. If so return encoded 8-bit value. 494ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee */ 502ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromstatic int EncodeImmDouble(int64_t value) { 514ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int res; 524ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int bit_a = (value & 0x8000000000000000ll) >> 63; 534ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int not_bit_b = (value & 0x4000000000000000ll) >> 62; 544ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int bit_b = (value & 0x2000000000000000ll) >> 61; 554ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int b_smear = (value & 0x3fc0000000000000ll) >> 54; 564ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int slice = (value & 0x003f000000000000ll) >> 48; 574ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee uint64_t zeroes = (value & 0x0000ffffffffffffll); 584ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (zeroes != 0) 594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return -1; 604ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (bit_b) { 614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if ((not_bit_b != 0) || (b_smear != 0xff)) 624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return -1; 634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 644ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if ((not_bit_b != 1) || (b_smear != 0x0)) 654ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return -1; 664ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee res = (bit_a << 7) | (bit_b << 6) | slice; 684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return res; 694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 712ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::LoadFPConstantValue(int r_dest, int value) { 72fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(ARM_SINGLEREG(r_dest)); 737da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee if (value == 0) { 747da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee // TODO: we need better info about the target CPU. a vector exclusive or 757da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee // would probably be better here if we could rely on its existance. 767da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee // Load an immediate +2.0 (which encodes to 0) 771fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vmovs_IMM8, r_dest, 0); 787da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee // +0.0 = +2.0 - +2.0 791fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(kThumb2Vsubs, r_dest, r_dest, r_dest); 807da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee } else { 817da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee int encoded_imm = EncodeImmSingle(value); 827da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee if (encoded_imm >= 0) { 831fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR2(kThumb2Vmovs_IMM8, r_dest, encoded_imm); 847da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee } 85a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 861fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* data_target = ScanLiteralPool(literal_list_, value, 0); 87fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (data_target == NULL) { 881fd3346740dfb7f47be9922312b68a4227fada96buzbee data_target = AddWordData(&literal_list_, value); 89a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 901fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* load_pc_rel = RawLIR(current_dalvik_offset_, kThumb2Vldrs, 91fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_dest, r15pc, 0, 0, 0, data_target); 921fd3346740dfb7f47be9922312b68a4227fada96buzbee SetMemRefType(load_pc_rel, true, kLiteral); 93fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee load_pc_rel->alias_info = reinterpret_cast<uintptr_t>(data_target); 941fd3346740dfb7f47be9922312b68a4227fada96buzbee AppendLIR(load_pc_rel); 95fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return load_pc_rel; 9667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 9767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 982ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromstatic int LeadingZeros(uint32_t val) { 99eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint32_t alt; 100a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int n; 101a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int count; 10267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 103a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee count = 16; 104a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee n = 32; 105a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee do { 106a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee alt = val >> count; 107a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (alt != 0) { 108a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee n = n - count; 109a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee val = alt; 110a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 111a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee count >>= 1; 112a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } while (count); 113a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return n - val; 11467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 11567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 11667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 11767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Determine whether value can be encoded as a Thumb2 modified 11867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * immediate. If not, return -1. If so, return i:imm3:a:bcdefgh form. 11967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 1202ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromint ArmMir2Lir::ModifiedImmediate(uint32_t value) { 1216f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom int z_leading; 1226f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom int z_trailing; 1236f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom uint32_t b0 = value & 0xff; 12467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1256f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom /* Note: case of value==0 must use 0:000:0:0000000 encoding */ 1266f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom if (value <= 0xFF) 1276f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom return b0; // 0:000:a:bcdefgh 1286f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom if (value == ((b0 << 16) | b0)) 1296f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom return (0x1 << 8) | b0; /* 0:001:a:bcdefgh */ 1306f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom if (value == ((b0 << 24) | (b0 << 16) | (b0 << 8) | b0)) 1316f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom return (0x3 << 8) | b0; /* 0:011:a:bcdefgh */ 1326f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom b0 = (value >> 8) & 0xff; 1336f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom if (value == ((b0 << 24) | (b0 << 8))) 1346f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom return (0x2 << 8) | b0; /* 0:010:a:bcdefgh */ 1356f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom /* Can we do it with rotation? */ 1366f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom z_leading = LeadingZeros(value); 1376f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom z_trailing = 32 - LeadingZeros(~value & (value - 1)); 1386f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom /* A run of eight or fewer active bits? */ 1396f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom if ((z_leading + z_trailing) < 24) 1406f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom return -1; /* No - bail */ 1416f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom /* left-justify the constant, discarding msb (known to be 1) */ 1426f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom value <<= z_leading + 1; 1436f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom /* Create bcdefgh */ 1446f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom value >>= 25; 1456f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom /* Put it all together */ 1466f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom return value | ((0x8 + z_leading) << 7); /* [01000..11111]:bcdefgh */ 14767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 14867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1492ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool ArmMir2Lir::InexpensiveConstantInt(int32_t value) { 1504ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return (ModifiedImmediate(value) >= 0) || (ModifiedImmediate(~value) >= 0); 1514ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 1524ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 1532ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool ArmMir2Lir::InexpensiveConstantFloat(int32_t value) { 1544ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return EncodeImmSingle(value) >= 0; 1554ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 1564ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 1572ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool ArmMir2Lir::InexpensiveConstantLong(int64_t value) { 1584ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return InexpensiveConstantInt(High32Bits(value)) && InexpensiveConstantInt(Low32Bits(value)); 1594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 1604ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 1612ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool ArmMir2Lir::InexpensiveConstantDouble(int64_t value) { 1624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return EncodeImmDouble(value) >= 0; 163e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee} 164e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee 16567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 16667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Load a immediate using a shortcut if possible; otherwise 16767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * grab from the per-translation literal pool. 16867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 16967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * No additional register clobbering operation performed. Use this version when 170fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * 1) r_dest is freshly returned from AllocTemp or 17167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 2) The codegen is under fixed register usage 17267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 1732ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::LoadConstantNoClobber(int r_dest, int value) { 174a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LIR* res; 175fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int mod_imm; 17667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 177fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_FPREG(r_dest)) { 1781fd3346740dfb7f47be9922312b68a4227fada96buzbee return LoadFPConstantValue(r_dest, value); 179a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 18067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 181a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* See if the value can be constructed cheaply */ 182fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_LOWREG(r_dest) && (value >= 0) && (value <= 255)) { 1831fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR2(kThumbMovImm, r_dest, value); 184a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 185a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Check Modified immediate special cases */ 186fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee mod_imm = ModifiedImmediate(value); 187fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (mod_imm >= 0) { 1881fd3346740dfb7f47be9922312b68a4227fada96buzbee res = NewLIR2(kThumb2MovImmShift, r_dest, mod_imm); 18967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee return res; 190a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 191fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee mod_imm = ModifiedImmediate(~value); 192fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (mod_imm >= 0) { 1931fd3346740dfb7f47be9922312b68a4227fada96buzbee res = NewLIR2(kThumb2MvnImm12, r_dest, mod_imm); 194a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return res; 195a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 196a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 16-bit immediate? */ 197a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if ((value & 0xffff) == value) { 1981fd3346740dfb7f47be9922312b68a4227fada96buzbee res = NewLIR2(kThumb2MovImm16, r_dest, value); 199a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return res; 200a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2014ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee /* Do a low/high pair */ 2021fd3346740dfb7f47be9922312b68a4227fada96buzbee res = NewLIR2(kThumb2MovImm16, r_dest, Low16Bits(value)); 2031fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2MovImm16H, r_dest, High16Bits(value)); 204a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return res; 20567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 20667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2072ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::OpUnconditionalBranch(LIR* target) { 2081fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* res = NewLIR1(kThumbBUncond, 0 /* offset to be patched during assembly*/); 20902031b185b4653e6c72e21f7a51238b903f6d638buzbee res->target = target; 21002031b185b4653e6c72e21f7a51238b903f6d638buzbee return res; 21167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 21267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2132ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::OpCondBranch(ConditionCode cc, LIR* target) { 2141fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch = NewLIR2(kThumb2BCond, 0 /* offset to be patched */, 21552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee ArmConditionEncoding(cc)); 216a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee branch->target = target; 217a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return branch; 21867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 21967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2202ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::OpReg(OpKind op, int r_dest_src) { 221a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ArmOpcode opcode = kThumbBkpt; 222a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (op) { 223a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpBlx: 224a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbBlxR; 225a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 226c0f96d03a1855fda7d94332331b94860404874ddBrian Carlstrom case kOpBx: 227c0f96d03a1855fda7d94332331b94860404874ddBrian Carlstrom opcode = kThumbBx; 228c0f96d03a1855fda7d94332331b94860404874ddBrian Carlstrom break; 229a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 230cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Bad opcode " << op; 231a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2321fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR1(opcode, r_dest_src); 23367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 23467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2351fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* ArmMir2Lir::OpRegRegShift(OpKind op, int r_dest_src1, int r_src2, 2362ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom int shift) { 237fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool thumb_form = ((shift == 0) && ARM_LOWREG(r_dest_src1) && ARM_LOWREG(r_src2)); 238a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ArmOpcode opcode = kThumbBkpt; 239a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (op) { 240a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAdc: 241fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbAdcRR : kThumb2AdcRRR; 242a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 243a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAnd: 244fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbAndRR : kThumb2AndRRR; 245a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 246a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpBic: 247fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbBicRR : kThumb2BicRRR; 248a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 249a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpCmn: 250a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 251fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbCmnRR : kThumb2CmnRR; 252a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 253a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpCmp: 254fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (thumb_form) 255a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbCmpRR; 256fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee else if ((shift == 0) && !ARM_LOWREG(r_dest_src1) && !ARM_LOWREG(r_src2)) 257a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbCmpHH; 258fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee else if ((shift == 0) && ARM_LOWREG(r_dest_src1)) 259a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbCmpLH; 260a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee else if (shift == 0) 261a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbCmpHL; 262a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee else 263a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2CmpRR; 264a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 265a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpXor: 266fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbEorRR : kThumb2EorRRR; 267a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 268a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpMov: 269a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 270fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_LOWREG(r_dest_src1) && ARM_LOWREG(r_src2)) 271a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbMovRR; 272fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee else if (!ARM_LOWREG(r_dest_src1) && !ARM_LOWREG(r_src2)) 273a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbMovRR_H2H; 274fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee else if (ARM_LOWREG(r_dest_src1)) 275a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbMovRR_H2L; 276a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee else 277a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbMovRR_L2H; 278a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 279a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpMul: 280a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 281fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbMul : kThumb2MulRRR; 282a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 283a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpMvn: 284fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbMvn : kThumb2MnvRR; 285a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 286a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpNeg: 287a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 288fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbNeg : kThumb2NegRR; 289a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 290a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpOr: 291fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbOrr : kThumb2OrrRRR; 292a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 293a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpSbc: 294fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbSbc : kThumb2SbcRRR; 295a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 296a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpTst: 297fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbTst : kThumb2TstRR; 298a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 299a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpLsl: 300a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 301fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbLslRR : kThumb2LslRRR; 302a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 303a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpLsr: 304a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 305fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbLsrRR : kThumb2LsrRRR; 306a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 307a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAsr: 308a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 309fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbAsrRR : kThumb2AsrRRR; 310a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 311a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpRor: 312a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 313fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbRorRR : kThumb2RorRRR; 314a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 315a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAdd: 316fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbAddRRR : kThumb2AddRRR; 317a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 318a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpSub: 319fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbSubRRR : kThumb2SubRRR; 320a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 321a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOp2Byte: 322a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 3231fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR4(kThumb2Sbfx, r_dest_src1, r_src2, 0, 8); 324a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOp2Short: 325a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 3261fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR4(kThumb2Sbfx, r_dest_src1, r_src2, 0, 16); 327a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOp2Char: 328a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 3291fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR4(kThumb2Ubfx, r_dest_src1, r_src2, 0, 16); 330a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 331cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Bad opcode: " << op; 332a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 333a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 334a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_GE(static_cast<int>(opcode), 0); 3359b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom if (EncodingMap[opcode].flags & IS_BINARY_OP) { 3361fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR2(opcode, r_dest_src1, r_src2); 3379b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom } else if (EncodingMap[opcode].flags & IS_TERTIARY_OP) { 3389b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom if (EncodingMap[opcode].field_loc[2].kind == kFmtShift) { 3391fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(opcode, r_dest_src1, r_src2, shift); 3409b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom } else { 3411fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(opcode, r_dest_src1, r_dest_src1, r_src2); 3429b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom } 3439b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom } else if (EncodingMap[opcode].flags & IS_QUAD_OP) { 3441fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR4(opcode, r_dest_src1, r_dest_src1, r_src2, shift); 3459b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom } else { 346a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(FATAL) << "Unexpected encoding operand count"; 347a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 348a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 34967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 35067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 3512ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::OpRegReg(OpKind op, int r_dest_src1, int r_src2) { 3521fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegRegShift(op, r_dest_src1, r_src2, 0); 35367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 35467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 3551fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* ArmMir2Lir::OpRegRegRegShift(OpKind op, int r_dest, int r_src1, 3562ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom int r_src2, int shift) { 357a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ArmOpcode opcode = kThumbBkpt; 358fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool thumb_form = (shift == 0) && ARM_LOWREG(r_dest) && ARM_LOWREG(r_src1) && 359fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ARM_LOWREG(r_src2); 360a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (op) { 361a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAdd: 362fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbAddRRR : kThumb2AddRRR; 363a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 364a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpSub: 365fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbSubRRR : kThumb2SubRRR; 366a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 367a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpRsub: 368a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2RsubRRR; 369a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 370a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAdc: 371a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2AdcRRR; 372a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 373a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAnd: 374a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2AndRRR; 375a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 376a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpBic: 377a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2BicRRR; 378a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 379a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpXor: 380a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2EorRRR; 381a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 382a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpMul: 383a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 384a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2MulRRR; 385a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 386a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpOr: 387a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2OrrRRR; 388a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 389a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpSbc: 390a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2SbcRRR; 391a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 392a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpLsl: 393a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 394a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2LslRRR; 395a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 396a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpLsr: 397a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 398a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2LsrRRR; 399a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 400a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAsr: 401a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 402a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2AsrRRR; 403a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 404a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpRor: 405a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ(shift, 0); 406a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2RorRRR; 407a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 408a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 409cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Bad opcode: " << op; 410a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 411a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 412a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_GE(static_cast<int>(opcode), 0); 4139b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom if (EncodingMap[opcode].flags & IS_QUAD_OP) { 4141fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR4(opcode, r_dest, r_src1, r_src2, shift); 4159b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom } else { 416a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK(EncodingMap[opcode].flags & IS_TERTIARY_OP); 4171fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(opcode, r_dest, r_src1, r_src2); 418a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 41967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 42067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 4212ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::OpRegRegReg(OpKind op, int r_dest, int r_src1, int r_src2) { 4221fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegRegRegShift(op, r_dest, r_src1, r_src2, 0); 42367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 42467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 4252ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::OpRegRegImm(OpKind op, int r_dest, int r_src1, int value) { 426a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LIR* res; 427a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee bool neg = (value < 0); 428fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int abs_value = (neg) ? -value : value; 429a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ArmOpcode opcode = kThumbBkpt; 430fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee ArmOpcode alt_opcode = kThumbBkpt; 431fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool all_low_regs = (ARM_LOWREG(r_dest) && ARM_LOWREG(r_src1)); 432fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int mod_imm = ModifiedImmediate(value); 433fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int mod_imm_neg = ModifiedImmediate(-value); 43467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 435a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (op) { 436a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpLsl: 437fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (all_low_regs) 4381fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(kThumbLslRRI5, r_dest, r_src1, value); 439a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee else 4401fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(kThumb2LslRRI5, r_dest, r_src1, value); 441a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpLsr: 442fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (all_low_regs) 4431fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(kThumbLsrRRI5, r_dest, r_src1, value); 444a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee else 4451fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(kThumb2LsrRRI5, r_dest, r_src1, value); 446a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAsr: 447fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (all_low_regs) 4481fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(kThumbAsrRRI5, r_dest, r_src1, value); 449a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee else 4501fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(kThumb2AsrRRI5, r_dest, r_src1, value); 451a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpRor: 4521fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(kThumb2RorRRI5, r_dest, r_src1, value); 453a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAdd: 454fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_LOWREG(r_dest) && (r_src1 == r13sp) && 45538f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom (value <= 1020) && ((value & 0x3) == 0)) { 4561fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(kThumbAddSpRel, r_dest, r_src1, value >> 2); 457fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (ARM_LOWREG(r_dest) && (r_src1 == r15pc) && 45838f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom (value <= 1020) && ((value & 0x3) == 0)) { 4591fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(kThumbAddPcRel, r_dest, r_src1, value >> 2); 460a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 461a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // Note: intentional fallthrough 462a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpSub: 463fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (all_low_regs && ((abs_value & 0x7) == abs_value)) { 464a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (op == kOpAdd) 465a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = (neg) ? kThumbSubRRI3 : kThumbAddRRI3; 46667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee else 467a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = (neg) ? kThumbAddRRI3 : kThumbSubRRI3; 4681fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(opcode, r_dest, r_src1, abs_value); 469fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if ((abs_value & 0xff) == abs_value) { 470a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (op == kOpAdd) 471a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = (neg) ? kThumb2SubRRI12 : kThumb2AddRRI12; 472a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee else 473a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = (neg) ? kThumb2AddRRI12 : kThumb2SubRRI12; 4741fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(opcode, r_dest, r_src1, abs_value); 475a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 476fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (mod_imm_neg >= 0) { 477a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op = (op == kOpAdd) ? kOpSub : kOpAdd; 478fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee mod_imm = mod_imm_neg; 479a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 480a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (op == kOpSub) { 481a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2SubRRI8; 482fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee alt_opcode = kThumb2SubRRR; 483a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 484a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2AddRRI8; 485fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee alt_opcode = kThumb2AddRRR; 486a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 487a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 488c7d1f91e024c5c560810376340aecb39d4e47fdcbuzbee case kOpRsub: 489c7d1f91e024c5c560810376340aecb39d4e47fdcbuzbee opcode = kThumb2RsubRRI8; 490c7d1f91e024c5c560810376340aecb39d4e47fdcbuzbee alt_opcode = kThumb2RsubRRR; 491c7d1f91e024c5c560810376340aecb39d4e47fdcbuzbee break; 492a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAdc: 493a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2AdcRRI8; 494fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee alt_opcode = kThumb2AdcRRR; 495a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 496a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpSbc: 497a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2SbcRRI8; 498fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee alt_opcode = kThumb2SbcRRR; 499a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 500a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpOr: 501a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2OrrRRI8; 502fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee alt_opcode = kThumb2OrrRRR; 503a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 504a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAnd: 505a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2AndRRI8; 506fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee alt_opcode = kThumb2AndRRR; 507a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 508a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpXor: 509a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2EorRRI8; 510fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee alt_opcode = kThumb2EorRRR; 511a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 512a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpMul: 5137934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom // TUNING: power of 2, shift & add 514fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee mod_imm = -1; 515fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee alt_opcode = kThumb2MulRRR; 516a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 517a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpCmp: { 518fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int mod_imm = ModifiedImmediate(value); 519a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LIR* res; 520fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (mod_imm >= 0) { 5211fd3346740dfb7f47be9922312b68a4227fada96buzbee res = NewLIR2(kThumb2CmpRI12, r_src1, mod_imm); 522a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 5231fd3346740dfb7f47be9922312b68a4227fada96buzbee int r_tmp = AllocTemp(); 5241fd3346740dfb7f47be9922312b68a4227fada96buzbee res = LoadConstant(r_tmp, value); 5251fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegReg(kOpCmp, r_src1, r_tmp); 5261fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(r_tmp); 527a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 528a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return res; 52967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 530a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 531cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Bad opcode: " << op; 532a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 533a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 534fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (mod_imm >= 0) { 5351fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(opcode, r_dest, r_src1, mod_imm); 536a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 5371fd3346740dfb7f47be9922312b68a4227fada96buzbee int r_scratch = AllocTemp(); 5381fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstant(r_scratch, value); 539fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (EncodingMap[alt_opcode].flags & IS_QUAD_OP) 5401fd3346740dfb7f47be9922312b68a4227fada96buzbee res = NewLIR4(alt_opcode, r_dest, r_src1, r_scratch, 0); 541a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee else 5421fd3346740dfb7f47be9922312b68a4227fada96buzbee res = NewLIR3(alt_opcode, r_dest, r_src1, r_scratch); 5431fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(r_scratch); 544a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return res; 545a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 54667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 54767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 54852a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee/* Handle Thumb-only variants here - otherwise punt to OpRegRegImm */ 5492ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::OpRegImm(OpKind op, int r_dest_src1, int value) { 550a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee bool neg = (value < 0); 551fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int abs_value = (neg) ? -value : value; 552fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool short_form = (((abs_value & 0xff) == abs_value) && ARM_LOWREG(r_dest_src1)); 553a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ArmOpcode opcode = kThumbBkpt; 554a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (op) { 555a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpAdd: 556df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom if (!neg && (r_dest_src1 == r13sp) && (value <= 508)) { /* sp */ 557a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ((value & 0x3), 0); 5581fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR1(kThumbAddSpI7, value >> 2); 559fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (short_form) { 560a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = (neg) ? kThumbSubRI8 : kThumbAddRI8; 561a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 562a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 563a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpSub: 564fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!neg && (r_dest_src1 == r13sp) && (value <= 508)) { /* sp */ 565a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ((value & 0x3), 0); 5661fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR1(kThumbSubSpI7, value >> 2); 567fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (short_form) { 568a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = (neg) ? kThumbAddRI8 : kThumbSubRI8; 569a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 570a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 571a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kOpCmp: 5729b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom if (ARM_LOWREG(r_dest_src1) && short_form) { 573fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (short_form) ? kThumbCmpRI8 : kThumbCmpRR; 5749b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom } else if (ARM_LOWREG(r_dest_src1)) { 575a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbCmpRR; 5769b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom } else { 577fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = false; 578a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbCmpHL; 579a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 580a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 581a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 58252a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee /* Punt to OpRegRegImm - if bad case catch it there */ 583fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = false; 584a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 585a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 5869b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom if (short_form) { 5871fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR2(opcode, r_dest_src1, abs_value); 5889b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom } else { 5891fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegRegImm(op, r_dest_src1, r_dest_src1, value); 590a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 59167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 59267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 5932ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::LoadConstantWide(int r_dest_lo, int r_dest_hi, int64_t value) { 5944ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee LIR* res = NULL; 5954ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int32_t val_lo = Low32Bits(value); 5964ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int32_t val_hi = High32Bits(value); 5977da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee int target_reg = S2d(r_dest_lo, r_dest_hi); 598fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_FPREG(r_dest_lo)) { 5997da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee if ((val_lo == 0) && (val_hi == 0)) { 6007da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee // TODO: we need better info about the target CPU. a vector exclusive or 6017da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee // would probably be better here if we could rely on its existance. 6027da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee // Load an immediate +2.0 (which encodes to 0) 6031fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kThumb2Vmovd_IMM8, target_reg, 0); 6047da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee // +0.0 = +2.0 - +2.0 6051fd3346740dfb7f47be9922312b68a4227fada96buzbee res = NewLIR3(kThumb2Vsubd, target_reg, target_reg, target_reg); 60667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } else { 6074ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int encoded_imm = EncodeImmDouble(value); 6087da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee if (encoded_imm >= 0) { 6091fd3346740dfb7f47be9922312b68a4227fada96buzbee res = NewLIR2(kThumb2Vmovd_IMM8, target_reg, encoded_imm); 610a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 61167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 612a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 6134ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if ((InexpensiveConstantInt(val_lo) && (InexpensiveConstantInt(val_hi)))) { 6141fd3346740dfb7f47be9922312b68a4227fada96buzbee res = LoadConstantNoClobber(r_dest_lo, val_lo); 6151fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstantNoClobber(r_dest_hi, val_hi); 6164ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 6174ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 6184ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (res == NULL) { 6194ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee // No short form - load from the literal pool. 6201fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* data_target = ScanLiteralPoolWide(literal_list_, val_lo, val_hi); 6214ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (data_target == NULL) { 6221fd3346740dfb7f47be9922312b68a4227fada96buzbee data_target = AddWideData(&literal_list_, val_lo, val_hi); 6234ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 6244ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (ARM_FPREG(r_dest_lo)) { 6251fd3346740dfb7f47be9922312b68a4227fada96buzbee res = RawLIR(current_dalvik_offset_, kThumb2Vldrd, 6264ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee target_reg, r15pc, 0, 0, 0, data_target); 6274ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 6281fd3346740dfb7f47be9922312b68a4227fada96buzbee res = RawLIR(current_dalvik_offset_, kThumb2LdrdPcRel8, 6294ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee r_dest_lo, r_dest_hi, r15pc, 0, 0, data_target); 6304ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 6311fd3346740dfb7f47be9922312b68a4227fada96buzbee SetMemRefType(res, true, kLiteral); 6324ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee res->alias_info = reinterpret_cast<uintptr_t>(data_target); 6331fd3346740dfb7f47be9922312b68a4227fada96buzbee AppendLIR(res); 634a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 635a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return res; 63667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 63767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 6381fd3346740dfb7f47be9922312b68a4227fada96buzbeeint ArmMir2Lir::EncodeShift(int code, int amount) { 639a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return ((amount & 0x1f) << 2) | code; 64067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 64167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 6421fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* ArmMir2Lir::LoadBaseIndexed(int rBase, int r_index, int r_dest, 6432ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom int scale, OpSize size) { 644fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool all_low_regs = ARM_LOWREG(rBase) && ARM_LOWREG(r_index) && ARM_LOWREG(r_dest); 645a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LIR* load; 646a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ArmOpcode opcode = kThumbBkpt; 647fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool thumb_form = (all_low_regs && (scale == 0)); 648fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int reg_ptr; 64967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 650fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_FPREG(r_dest)) { 651fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_SINGLEREG(r_dest)) { 652a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK((size == kWord) || (size == kSingle)); 653a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2Vldrs; 654a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee size = kSingle; 65567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } else { 656fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(ARM_DOUBLEREG(r_dest)); 657a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK((size == kLong) || (size == kDouble)); 658fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ((r_dest & 0x1), 0); 659a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2Vldrd; 660a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee size = kDouble; 66167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 662a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 663a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (size == kSingle) 664a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee size = kWord; 665a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 66667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 667a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (size) { 6687934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom case kDouble: // fall-through 669a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kSingle: 6701fd3346740dfb7f47be9922312b68a4227fada96buzbee reg_ptr = AllocTemp(); 671a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (scale) { 6721fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR4(kThumb2AddRRR, reg_ptr, rBase, r_index, 67352a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee EncodeShift(kArmLsl, scale)); 674a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 6751fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegRegReg(kOpAdd, reg_ptr, rBase, r_index); 676a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 6771fd3346740dfb7f47be9922312b68a4227fada96buzbee load = NewLIR3(opcode, r_dest, reg_ptr, 0); 6781fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(reg_ptr); 679a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return load; 680a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kWord: 681fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbLdrRRR : kThumb2LdrRRR; 682a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 683a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kUnsignedHalf: 684fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbLdrhRRR : kThumb2LdrhRRR; 685a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 686a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kSignedHalf: 687fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbLdrshRRR : kThumb2LdrshRRR; 688a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 689a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kUnsignedByte: 690fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbLdrbRRR : kThumb2LdrbRRR; 691a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 692a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kSignedByte: 693fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbLdrsbRRR : kThumb2LdrsbRRR; 694a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 695a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 696cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Bad size: " << size; 697a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 698fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (thumb_form) 6991fd3346740dfb7f47be9922312b68a4227fada96buzbee load = NewLIR3(opcode, r_dest, rBase, r_index); 700a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee else 7011fd3346740dfb7f47be9922312b68a4227fada96buzbee load = NewLIR4(opcode, r_dest, rBase, r_index, scale); 70267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 703a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return load; 70467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 70567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 7061fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* ArmMir2Lir::StoreBaseIndexed(int rBase, int r_index, int r_src, 7072ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom int scale, OpSize size) { 708fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool all_low_regs = ARM_LOWREG(rBase) && ARM_LOWREG(r_index) && ARM_LOWREG(r_src); 7094ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee LIR* store = NULL; 710a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ArmOpcode opcode = kThumbBkpt; 711fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool thumb_form = (all_low_regs && (scale == 0)); 712fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int reg_ptr; 71367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 714fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_FPREG(r_src)) { 715fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_SINGLEREG(r_src)) { 716a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK((size == kWord) || (size == kSingle)); 717a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2Vstrs; 718a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee size = kSingle; 71967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } else { 720fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(ARM_DOUBLEREG(r_src)); 721a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK((size == kLong) || (size == kDouble)); 722fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ((r_src & 0x1), 0); 723a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2Vstrd; 724a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee size = kDouble; 72567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 726a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 727a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (size == kSingle) 728a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee size = kWord; 729a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 73067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 731a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (size) { 7327934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom case kDouble: // fall-through 733a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kSingle: 7341fd3346740dfb7f47be9922312b68a4227fada96buzbee reg_ptr = AllocTemp(); 735a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (scale) { 7361fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR4(kThumb2AddRRR, reg_ptr, rBase, r_index, 73752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee EncodeShift(kArmLsl, scale)); 738a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 7391fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegRegReg(kOpAdd, reg_ptr, rBase, r_index); 740a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 7411fd3346740dfb7f47be9922312b68a4227fada96buzbee store = NewLIR3(opcode, r_src, reg_ptr, 0); 7421fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(reg_ptr); 743a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return store; 744a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kWord: 745fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbStrRRR : kThumb2StrRRR; 746a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 747a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kUnsignedHalf: 748a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kSignedHalf: 749fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbStrhRRR : kThumb2StrhRRR; 750a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 751a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kUnsignedByte: 752a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kSignedByte: 753fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = (thumb_form) ? kThumbStrbRRR : kThumb2StrbRRR; 754a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 755a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 756cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Bad size: " << size; 757a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 758fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (thumb_form) 7591fd3346740dfb7f47be9922312b68a4227fada96buzbee store = NewLIR3(opcode, r_src, rBase, r_index); 760a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee else 7611fd3346740dfb7f47be9922312b68a4227fada96buzbee store = NewLIR4(opcode, r_src, rBase, r_index, scale); 76267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 763a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return store; 76467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 76567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 76667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 76767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Load value from base + displacement. Optionally perform null check 768fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * on base (which must have an associated s_reg and MIR). If not 76967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * performing null check, incoming MIR can be null. 77067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 7711fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* ArmMir2Lir::LoadBaseDispBody(int rBase, int displacement, int r_dest, 7722ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom int r_dest_hi, OpSize size, int s_reg) { 7734ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee LIR* load = NULL; 774a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ArmOpcode opcode = kThumbBkpt; 775fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool short_form = false; 776a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee bool thumb2Form = (displacement < 4092 && displacement >= 0); 777fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool all_low_regs = (ARM_LOWREG(rBase) && ARM_LOWREG(r_dest)); 778fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int encoded_disp = displacement; 779a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee bool is64bit = false; 7804ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee bool already_generated = false; 781a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (size) { 782a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kDouble: 783a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kLong: 784a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee is64bit = true; 785fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_FPREG(r_dest)) { 786fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_SINGLEREG(r_dest)) { 787fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(ARM_FPREG(r_dest_hi)); 7881fd3346740dfb7f47be9922312b68a4227fada96buzbee r_dest = S2d(r_dest, r_dest_hi); 789a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 790a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2Vldrd; 791a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (displacement <= 1020) { 792fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 793fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee encoded_disp >>= 2; 794a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 795a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 796a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 7974ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (displacement <= 1020) { 7981fd3346740dfb7f47be9922312b68a4227fada96buzbee load = NewLIR4(kThumb2LdrdI8, r_dest, r_dest_hi, rBase, displacement >> 2); 7994ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 8001fd3346740dfb7f47be9922312b68a4227fada96buzbee load = LoadBaseDispBody(rBase, displacement, r_dest, 8014ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee -1, kWord, s_reg); 8021fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadBaseDispBody(rBase, displacement + 4, r_dest_hi, 8034ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee -1, kWord, INVALID_SREG); 8044ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 8054ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee already_generated = true; 806a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 807a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kSingle: 808a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kWord: 809fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_FPREG(r_dest)) { 810a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2Vldrs; 811a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (displacement <= 1020) { 812fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 813fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee encoded_disp >>= 2; 814a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 815a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 816a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 817fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_LOWREG(r_dest) && (rBase == r15pc) && 818a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee (displacement <= 1020) && (displacement >= 0)) { 819fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 820fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee encoded_disp >>= 2; 821a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbLdrPcRel; 822fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (ARM_LOWREG(r_dest) && (rBase == r13sp) && 823a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee (displacement <= 1020) && (displacement >= 0)) { 824fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 825fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee encoded_disp >>= 2; 826a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbLdrSpRel; 827fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (all_low_regs && displacement < 128 && displacement >= 0) { 828a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ((displacement & 0x3), 0); 829fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 830fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee encoded_disp >>= 2; 831a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbLdrRRI5; 832a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else if (thumb2Form) { 833fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 834a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2LdrRRI12; 835a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 836a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 837a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kUnsignedHalf: 838fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (all_low_regs && displacement < 64 && displacement >= 0) { 839a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ((displacement & 0x1), 0); 840fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 841fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee encoded_disp >>= 1; 842a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbLdrhRRI5; 843a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else if (displacement < 4092 && displacement >= 0) { 844fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 845a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2LdrhRRI12; 846a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 847a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 848a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kSignedHalf: 849a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (thumb2Form) { 850fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 851a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2LdrshRRI12; 852a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 853a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 854a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kUnsignedByte: 855fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (all_low_regs && displacement < 32 && displacement >= 0) { 856fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 857a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbLdrbRRI5; 858a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else if (thumb2Form) { 859fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 860a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2LdrbRRI12; 861a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 862a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 863a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kSignedByte: 864a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (thumb2Form) { 865fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 866a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2LdrsbRRI12; 867a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 868a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 869a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 870cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Bad size: " << size; 871a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 87267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 8734ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (!already_generated) { 8744ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (short_form) { 8751fd3346740dfb7f47be9922312b68a4227fada96buzbee load = NewLIR3(opcode, r_dest, rBase, encoded_disp); 8764ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 8771fd3346740dfb7f47be9922312b68a4227fada96buzbee int reg_offset = AllocTemp(); 8781fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstant(reg_offset, encoded_disp); 8791fd3346740dfb7f47be9922312b68a4227fada96buzbee load = LoadBaseIndexed(rBase, reg_offset, r_dest, 0, size); 8801fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(reg_offset); 8814ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 882a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 88367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 884a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // TODO: in future may need to differentiate Dalvik accesses w/ spills 885f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee if (rBase == rARM_SP) { 8861fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(load, displacement >> 2, true /* is_load */, is64bit); 887a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 888a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return load; 88967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 89067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 8911fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* ArmMir2Lir::LoadBaseDisp(int rBase, int displacement, int r_dest, 8922ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom OpSize size, int s_reg) { 8931fd3346740dfb7f47be9922312b68a4227fada96buzbee return LoadBaseDispBody(rBase, displacement, r_dest, -1, size, s_reg); 89467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 89567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 8961fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* ArmMir2Lir::LoadBaseDispWide(int rBase, int displacement, int r_dest_lo, 8972ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom int r_dest_hi, int s_reg) { 8981fd3346740dfb7f47be9922312b68a4227fada96buzbee return LoadBaseDispBody(rBase, displacement, r_dest_lo, r_dest_hi, kLong, s_reg); 89967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 90067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 90167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 9021fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* ArmMir2Lir::StoreBaseDispBody(int rBase, int displacement, 90302031b185b4653e6c72e21f7a51238b903f6d638buzbee int r_src, int r_src_hi, OpSize size) { 9044ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee LIR* store = NULL; 905a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee ArmOpcode opcode = kThumbBkpt; 906fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool short_form = false; 907a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee bool thumb2Form = (displacement < 4092 && displacement >= 0); 908fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool all_low_regs = (ARM_LOWREG(rBase) && ARM_LOWREG(r_src)); 909fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int encoded_disp = displacement; 910a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee bool is64bit = false; 9114ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee bool already_generated = false; 912a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (size) { 913a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kLong: 914a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kDouble: 915a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee is64bit = true; 916fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!ARM_FPREG(r_src)) { 9174ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (displacement <= 1020) { 9181fd3346740dfb7f47be9922312b68a4227fada96buzbee store = NewLIR4(kThumb2StrdI8, r_src, r_src_hi, rBase, displacement >> 2); 9194ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 9201fd3346740dfb7f47be9922312b68a4227fada96buzbee store = StoreBaseDispBody(rBase, displacement, r_src, -1, kWord); 9211fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreBaseDispBody(rBase, displacement + 4, r_src_hi, -1, kWord); 9224ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 9234ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee already_generated = true; 9244ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 9254ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (ARM_SINGLEREG(r_src)) { 9264ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee DCHECK(ARM_FPREG(r_src_hi)); 9271fd3346740dfb7f47be9922312b68a4227fada96buzbee r_src = S2d(r_src, r_src_hi); 9284ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 9294ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee opcode = kThumb2Vstrd; 9304ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (displacement <= 1020) { 9314ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee short_form = true; 9324ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee encoded_disp >>= 2; 9334ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 934a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 935a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 936a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kSingle: 937a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kWord: 938fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_FPREG(r_src)) { 939fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(ARM_SINGLEREG(r_src)); 940a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2Vstrs; 941a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee if (displacement <= 1020) { 942fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 943fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee encoded_disp >>= 2; 944a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 945a188cd4ad38aa561742d5f3f5b45215f451cb834Sebastien Hertz break; 946a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 947a188cd4ad38aa561742d5f3f5b45215f451cb834Sebastien Hertz if (ARM_LOWREG(r_src) && (rBase == r13sp) && 948a188cd4ad38aa561742d5f3f5b45215f451cb834Sebastien Hertz (displacement <= 1020) && (displacement >= 0)) { 949a188cd4ad38aa561742d5f3f5b45215f451cb834Sebastien Hertz short_form = true; 950a188cd4ad38aa561742d5f3f5b45215f451cb834Sebastien Hertz encoded_disp >>= 2; 951a188cd4ad38aa561742d5f3f5b45215f451cb834Sebastien Hertz opcode = kThumbStrSpRel; 952a188cd4ad38aa561742d5f3f5b45215f451cb834Sebastien Hertz } else if (all_low_regs && displacement < 128 && displacement >= 0) { 953a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ((displacement & 0x3), 0); 954fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 955fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee encoded_disp >>= 2; 956a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbStrRRI5; 957a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else if (thumb2Form) { 958fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 959a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2StrRRI12; 960a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 961a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 962a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kUnsignedHalf: 963a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kSignedHalf: 964fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (all_low_regs && displacement < 64 && displacement >= 0) { 965a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee DCHECK_EQ((displacement & 0x1), 0); 966fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 967fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee encoded_disp >>= 1; 968a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbStrhRRI5; 969a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else if (thumb2Form) { 970fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 971a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2StrhRRI12; 972a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 973a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 974a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kUnsignedByte: 975a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kSignedByte: 976fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (all_low_regs && displacement < 32 && displacement >= 0) { 977fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 978a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumbStrbRRI5; 979a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else if (thumb2Form) { 980fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee short_form = true; 981a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2StrbRRI12; 982a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 983a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 984a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 985cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(FATAL) << "Bad size: " << size; 986a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 9874ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (!already_generated) { 9884ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (short_form) { 9891fd3346740dfb7f47be9922312b68a4227fada96buzbee store = NewLIR3(opcode, r_src, rBase, encoded_disp); 9904ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 9911fd3346740dfb7f47be9922312b68a4227fada96buzbee int r_scratch = AllocTemp(); 9921fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstant(r_scratch, encoded_disp); 9931fd3346740dfb7f47be9922312b68a4227fada96buzbee store = StoreBaseIndexed(rBase, r_scratch, r_src, 0, size); 9941fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(r_scratch); 9954ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 996a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 99767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 998a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // TODO: In future, may need to differentiate Dalvik & spill accesses 999f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee if (rBase == rARM_SP) { 10001fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(store, displacement >> 2, false /* is_load */, is64bit); 1001a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 10024ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return store; 100367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 100467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 10051fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* ArmMir2Lir::StoreBaseDisp(int rBase, int displacement, int r_src, 10062ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom OpSize size) { 10071fd3346740dfb7f47be9922312b68a4227fada96buzbee return StoreBaseDispBody(rBase, displacement, r_src, -1, size); 100867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 100967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 10101fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* ArmMir2Lir::StoreBaseDispWide(int rBase, int displacement, 10112ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom int r_src_lo, int r_src_hi) { 10121fd3346740dfb7f47be9922312b68a4227fada96buzbee return StoreBaseDispBody(rBase, displacement, r_src_lo, r_src_hi, kLong); 101367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 101467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 10152ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::OpFpRegCopy(int r_dest, int r_src) { 1016a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int opcode; 1017fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(ARM_DOUBLEREG(r_dest), ARM_DOUBLEREG(r_src)); 1018fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_DOUBLEREG(r_dest)) { 1019a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2Vmovd; 1020a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 1021fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (ARM_SINGLEREG(r_dest)) { 1022fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = ARM_SINGLEREG(r_src) ? kThumb2Vmovs : kThumb2Fmsr; 102367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } else { 1024fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(ARM_SINGLEREG(r_src)); 1025a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kThumb2Fmrs; 102667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 1027a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 10281fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* res = RawLIR(current_dalvik_offset_, opcode, r_dest, r_src); 10291fd3346740dfb7f47be9922312b68a4227fada96buzbee if (!(cu_->disable_opt & (1 << kSafeOptimizations)) && r_dest == r_src) { 1030fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res->flags.is_nop = true; 1031a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 1032a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return res; 103367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 103467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1035468532ea115657709bc32ee498e701a4c71762d4Ian RogersLIR* ArmMir2Lir::OpThreadMem(OpKind op, ThreadOffset thread_offset) { 103652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Unexpected use of OpThreadMem for Arm"; 1037b046e16d8b8da318d6055f9308950131f1255e08buzbee return NULL; 1038b046e16d8b8da318d6055f9308950131f1255e08buzbee} 1039b046e16d8b8da318d6055f9308950131f1255e08buzbee 10402ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::OpMem(OpKind op, int rBase, int disp) { 104152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Unexpected use of OpMem for Arm"; 1042b046e16d8b8da318d6055f9308950131f1255e08buzbee return NULL; 1043b046e16d8b8da318d6055f9308950131f1255e08buzbee} 104467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 10451fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* ArmMir2Lir::StoreBaseIndexedDisp(int rBase, int r_index, int scale, 104602031b185b4653e6c72e21f7a51238b903f6d638buzbee int displacement, int r_src, int r_src_hi, OpSize size, 10472ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom int s_reg) { 104852a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Unexpected use of StoreBaseIndexedDisp for Arm"; 1049b046e16d8b8da318d6055f9308950131f1255e08buzbee return NULL; 1050b046e16d8b8da318d6055f9308950131f1255e08buzbee} 1051b046e16d8b8da318d6055f9308950131f1255e08buzbee 10522ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* ArmMir2Lir::OpRegMem(OpKind op, int r_dest, int rBase, int offset) { 105352a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Unexpected use of OpRegMem for Arm"; 1054b046e16d8b8da318d6055f9308950131f1255e08buzbee return NULL; 1055b046e16d8b8da318d6055f9308950131f1255e08buzbee} 1056b046e16d8b8da318d6055f9308950131f1255e08buzbee 10571fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* ArmMir2Lir::LoadBaseIndexedDisp(int rBase, int r_index, int scale, 105802031b185b4653e6c72e21f7a51238b903f6d638buzbee int displacement, int r_dest, int r_dest_hi, OpSize size, 10592ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom int s_reg) { 106052a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Unexpected use of LoadBaseIndexedDisp for Arm"; 1061b046e16d8b8da318d6055f9308950131f1255e08buzbee return NULL; 1062b046e16d8b8da318d6055f9308950131f1255e08buzbee} 106311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 106411d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes} // namespace art 1065