Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include "native_client/src/trusted/validator_arm/inst_classes.h" | 7 #include "native_client/src/trusted/validator_arm/inst_classes.h" |
| 8 | 8 |
| 9 /* | 9 /* |
| 10 * Implementations of instruction classes, for those not completely defined in | 10 * Implementations of instruction classes, for those not completely defined in |
| 11 * the header. | 11 * the header. |
| 12 */ | 12 */ |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; | 208 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; |
| 209 | 209 |
| 210 return MAY_BE_SAFE; | 210 return MAY_BE_SAFE; |
| 211 } | 211 } |
| 212 | 212 |
| 213 RegisterList AbstractLoad::defs(const Instruction i) const { | 213 RegisterList AbstractLoad::defs(const Instruction i) const { |
| 214 return i.reg(15, 12) + immediate_addressing_defs(i); | 214 return i.reg(15, 12) + immediate_addressing_defs(i); |
| 215 } | 215 } |
| 216 | 216 |
| 217 | 217 |
| 218 SafetyLevel LoadRegister::safety(const Instruction i) const { | |
| 219 bool pre_index = i.bit(24); | |
|
jasonwkim
2011/10/13 23:05:41
some comments?
| |
| 220 if (pre_index) { | |
| 221 // Computes base address by adding two registers -- cannot predict! | |
| 222 return FORBIDDEN; | |
| 223 } | |
| 224 | |
| 225 // Don't let addressing writeback alter PC. | |
| 226 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; | |
| 227 | |
| 228 return MAY_BE_SAFE; | |
| 229 } | |
| 230 | |
| 218 RegisterList LoadRegister::defs(const Instruction i) const { | 231 RegisterList LoadRegister::defs(const Instruction i) const { |
| 219 if (writeback(i)) { | 232 if (writeback(i)) { |
| 220 Register rn(i.bits(19, 16)); | 233 Register rn(i.bits(19, 16)); |
| 221 return AbstractLoad::defs(i) + rn; | 234 return AbstractLoad::defs(i) + rn; |
| 222 } else { | 235 } else { |
| 223 return AbstractLoad::defs(i); | 236 return AbstractLoad::defs(i); |
| 224 } | 237 } |
| 225 } | 238 } |
| 226 | 239 |
| 240 Register LoadRegister::base_address_register(const Instruction i) const { | |
| 241 return i.reg(19, 16); | |
| 242 } | |
| 243 | |
| 227 | 244 |
| 228 RegisterList LoadImmediate::immediate_addressing_defs(const Instruction i) | 245 RegisterList LoadImmediate::immediate_addressing_defs(const Instruction i) |
| 229 const { | 246 const { |
| 230 if (writeback(i)) { | 247 if (writeback(i)) { |
| 231 Register rn(i.bits(19, 16)); | 248 Register rn(i.bits(19, 16)); |
| 232 return rn; | 249 return rn; |
| 233 } else { | 250 } else { |
| 234 return kRegisterNone; | 251 return kRegisterNone; |
| 235 } | 252 } |
| 236 } | 253 } |
| 237 | 254 |
| 255 Register LoadImmediate::base_address_register(const Instruction i) const { | |
| 256 return i.reg(19, 16); | |
| 257 } | |
| 258 | |
| 259 bool LoadImmediate::offset_is_immediate(Instruction i) const { | |
| 260 UNREFERENCED_PARAMETER(i); | |
| 261 return true; | |
| 262 } | |
| 263 | |
| 238 | 264 |
| 239 RegisterList LoadDoubleI::defs(const Instruction i) const { | 265 RegisterList LoadDoubleI::defs(const Instruction i) const { |
| 240 return LoadImmediate::defs(i) + Register(i.bits(15, 12) + 1); | 266 return LoadImmediate::defs(i) + Register(i.bits(15, 12) + 1); |
| 241 } | 267 } |
| 242 | 268 |
| 269 Register LoadDoubleI::base_address_register(const Instruction i) const { | |
| 270 return i.reg(19, 16); | |
| 271 } | |
| 272 | |
| 273 bool LoadDoubleI::offset_is_immediate(Instruction i) const { | |
| 274 UNREFERENCED_PARAMETER(i); | |
| 275 return true; | |
| 276 } | |
| 277 | |
| 278 | |
| 279 SafetyLevel LoadDoubleR::safety(const Instruction i) const { | |
| 280 bool pre_index = i.bit(24); | |
| 281 if (pre_index) { | |
|
jasonwkim
2011/10/13 23:05:41
ditto
| |
| 282 // Computes base address by adding two registers -- cannot predict! | |
| 283 return FORBIDDEN; | |
| 284 } | |
| 285 | |
| 286 // Don't let addressing writeback alter PC. | |
| 287 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; | |
| 288 | |
| 289 return MAY_BE_SAFE; | |
| 290 } | |
| 243 | 291 |
| 244 RegisterList LoadDoubleR::defs(const Instruction i) const { | 292 RegisterList LoadDoubleR::defs(const Instruction i) const { |
| 245 return LoadRegister::defs(i) + Register(i.bits(15, 12) + 1); | 293 return LoadRegister::defs(i) + Register(i.bits(15, 12) + 1); |
| 246 } | 294 } |
| 247 | 295 |
| 296 Register LoadDoubleR::base_address_register(const Instruction i) const { | |
| 297 return i.reg(19, 16); | |
| 298 } | |
| 299 | |
| 248 RegisterList LoadDoubleExclusive::defs(const Instruction i) const { | 300 RegisterList LoadDoubleExclusive::defs(const Instruction i) const { |
| 249 return LoadExclusive::defs(i) + Register(i.bits(15, 12) + 1); | 301 return LoadExclusive::defs(i) + Register(i.bits(15, 12) + 1); |
| 250 } | 302 } |
| 251 | 303 |
| 304 Register LoadDoubleExclusive::base_address_register(const Instruction i) const { | |
| 305 return i.reg(19, 16); | |
| 306 } | |
| 307 | |
| 252 | 308 |
| 253 SafetyLevel LoadMultiple::safety(const Instruction i) const { | 309 SafetyLevel LoadMultiple::safety(const Instruction i) const { |
| 254 uint32_t rn = i.bits(19, 16); | 310 uint32_t rn = i.bits(19, 16); |
| 255 if (i.bit(21) && i.bit(rn)) { | 311 if (i.bit(21) && i.bit(rn)) { |
| 256 // In ARMv7, cannot update base register both by popping and by indexing. | 312 // In ARMv7, cannot update base register both by popping and by indexing. |
| 257 // (Pre-v7 this was still a weird thing to do.) | 313 // (Pre-v7 this was still a weird thing to do.) |
| 258 return UNPREDICTABLE; | 314 return UNPREDICTABLE; |
| 259 } | 315 } |
| 260 | 316 |
| 261 if (defs(i)[kRegisterPc]) { | 317 if (defs(i)[kRegisterPc]) { |
| 262 return FORBIDDEN_OPERANDS; | 318 return FORBIDDEN_OPERANDS; |
| 263 } | 319 } |
| 264 return MAY_BE_SAFE; | 320 return MAY_BE_SAFE; |
| 265 } | 321 } |
| 266 | 322 |
| 267 RegisterList LoadMultiple::defs(const Instruction i) const { | 323 RegisterList LoadMultiple::defs(const Instruction i) const { |
| 268 return RegisterList(i.bits(15, 0)) + immediate_addressing_defs(i); | 324 return RegisterList(i.bits(15, 0)) + immediate_addressing_defs(i); |
| 269 } | 325 } |
| 270 | 326 |
| 271 RegisterList LoadMultiple::immediate_addressing_defs( | 327 RegisterList LoadMultiple::immediate_addressing_defs( |
| 272 const Instruction i) const { | 328 const Instruction i) const { |
| 273 return i.bit(21)? i.reg(19, 16) : kRegisterNone; | 329 return i.bit(21)? i.reg(19, 16) : kRegisterNone; |
| 274 } | 330 } |
| 275 | 331 |
| 332 Register LoadMultiple::base_address_register(const Instruction i) const { | |
| 333 return i.reg(19, 16); | |
| 334 } | |
| 335 | |
| 276 | 336 |
| 277 /* | 337 /* |
| 278 * Vector load/stores | 338 * Vector load/stores |
| 279 */ | 339 */ |
| 280 | 340 |
| 281 SafetyLevel VectorLoad::safety(Instruction i) const { | 341 SafetyLevel VectorLoad::safety(Instruction i) const { |
| 282 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; | 342 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; |
| 283 | 343 |
| 284 return MAY_BE_SAFE; | 344 return MAY_BE_SAFE; |
| 285 } | 345 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 297 // Rm == SP indicates automatic update based on size of load. | 357 // Rm == SP indicates automatic update based on size of load. |
| 298 if (i.reg(3, 0) == kRegisterStack) { | 358 if (i.reg(3, 0) == kRegisterStack) { |
| 299 // Rn is updated by a small static displacement. | 359 // Rn is updated by a small static displacement. |
| 300 return i.reg(19, 16); | 360 return i.reg(19, 16); |
| 301 } | 361 } |
| 302 | 362 |
| 303 // Any writeback is not treated as immediate otherwise. | 363 // Any writeback is not treated as immediate otherwise. |
| 304 return kRegisterNone; | 364 return kRegisterNone; |
| 305 } | 365 } |
| 306 | 366 |
| 367 Register VectorLoad::base_address_register(const Instruction i) const { | |
| 368 return i.reg(19, 16); | |
| 369 } | |
| 370 | |
| 307 | 371 |
| 308 SafetyLevel VectorStore::safety(Instruction i) const { | 372 SafetyLevel VectorStore::safety(Instruction i) const { |
| 309 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; | 373 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; |
| 310 | 374 |
| 311 return MAY_BE_SAFE; | 375 return MAY_BE_SAFE; |
| 312 } | 376 } |
| 313 | 377 |
| 314 RegisterList VectorStore::defs(Instruction i) const { | 378 RegisterList VectorStore::defs(Instruction i) const { |
| 315 // Rm == PC indicates no address writeback. Otherwise Rn is affected. | 379 // Rm == PC indicates no address writeback. Otherwise Rn is affected. |
| 316 if (i.reg(3, 0) != kRegisterPc) { | 380 if (i.reg(3, 0) != kRegisterPc) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 413 return kRegisterPc + (i.bit(24)? kRegisterLink : kRegisterNone); | 477 return kRegisterPc + (i.bit(24)? kRegisterLink : kRegisterNone); |
| 414 } | 478 } |
| 415 | 479 |
| 416 int32_t Branch::branch_target_offset(const Instruction i) const { | 480 int32_t Branch::branch_target_offset(const Instruction i) const { |
| 417 // Sign extend and shift left 2: | 481 // Sign extend and shift left 2: |
| 418 int32_t offset = (int32_t)(i.bits(23, 0) << 8) >> 6; | 482 int32_t offset = (int32_t)(i.bits(23, 0) << 8) >> 6; |
| 419 return offset + 8; // because r15 reads as 8 bytes ahead | 483 return offset + 8; // because r15 reads as 8 bytes ahead |
| 420 } | 484 } |
| 421 | 485 |
| 422 } // namespace | 486 } // namespace |
| OLD | NEW |