有没有办法通过两个数字/寄存器之和执行左移逻辑?
我正在考虑看起来像这样的东西,但实际上有效:
buildscript {
repositories {
jcenter()
maven { url 'https://maven.fabric.io/public' }
maven {
url 'https://maven.google.com/'
name 'Google'
}
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.google.gms:google-services:4.0.0'
/*classpath 'com.google.gms:google-services:3.1.0'*/
classpath 'io.fabric.tools:gradle:1.+'
classpath 'com.google.ar.sceneform:plugin:1.6.0'
}
}
configurations {
all {
exclude module: 'httpclient'
exclude module: 'commons-logging'
}
}
allprojects {
repositories {
jcenter()
mavenCentral()
maven { url "http://jitpack.io" }
maven {
url "https://maven.google.com" // specifically this worked
}
google()
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
repositories {
maven { url 'https://maven.fabric.io/public' }
maven {
url 'https://maven.google.com/'
name 'Google'
}
}
android {
signingConfigs {
config {
//config data
}
}
dexOptions {
jumboMode true
javaMaxHeapSize "4g"
}
lintOptions {
checkReleaseBuilds false
disable 'MissingTranslation'
}
compileSdkVersion 28
buildToolsVersion '28.0.3'
useLibrary 'org.apache.http.legacy'
defaultConfig {
applicationId "com.app.id
vectorDrawables.useSupportLibrary = true
renderscriptTargetApi 23
minSdkVersion 19
targetSdkVersion 28
renderscriptSupportModeEnabled true
multiDexEnabled true
}
buildTypes {
release {
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
4
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
// Move the tests to tests/java, tests/res, etc...
androidTest.setRoot('tests')
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
}
答案 0 :(得分:1)
您需要两条指令(以计算tmp寄存器中的移位计数)。
(除非两个数字都是常量。lsl r4, r1, #1 + #2
可以在汇编时求和到lsl r4, r1, #3
。)
寄存器+立即数或寄存器+注册在ARM机器代码中不可编码。仅有少数几个位对移位模式(左,右逻辑,右算术,右旋转以及立即数或寄存器计数)和移位计数(寄存器号或立即数计数,但不能同时编码)进行编码。
ASM源只是一种用文本描述机器代码指令的方法。它与C不同,您可以编写更复杂的表达式并将其编译为多个指令。因此存在这些限制是由于机器代码编码的限制,而不是因为asm语法/语言设计的选择。
({ldr r0, =0x12345678
是一条伪指令,它确实可以汇编为多个指令,或者可以从附近的文字池中加载PC相对负载。但是,除了一些伪指令可以构造更大的值不能作为一个32位ARM或16位thumb / thumb2指令的一部分放在一个字段中,则一个asm指令必须汇编为一条机器指令。)
根据https://www.scss.tcd.ie/John.Waldron/3d1/barrelshift.pdf,移位计数可以 为5位立即数,或指定为寄存器的低字节。绝对不是两者。
我不认为您可以使用任何完全不同的说明。例如您只能移位一个操作数,因此无法通过将两个输入向add
左移相同的量来获得额外的一位移位。
如果代码使用的结果可以在以后应用该班次的恒定部分,您也许可以优化掉额外的即时班次。
我不确定使用桶形移位器是否会在某些ARM uarches上增加任何延迟,但是如果是这样,那么在循环中有很多指令都执行一个额外的移位(而不是一个额外的指令)是不理想的将移位结果保存在寄存器中。
当然,如果要将它与需要移位其另一个操作数的指令一起使用,则需要最终值。