通过两个数字/寄存器的总和左移逻辑?

时间:2018-12-26 04:11:37

标签: assembly arm bit-shift instruction-set

有没有办法通过两个数字/寄存器之和执行左移逻辑?

我正在考虑看起来像这样的东西,但实际上有效:

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')
}
}

1 个答案:

答案 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上增加任何延迟,但是如果是这样,那么在循环中有很多指令都执行一个额外的移位(而不是一个额外的指令)是不理想的将移位结果保存在寄存器中。

当然,如果要将它与需要移位其另一个操作数的指令一起使用,则需要最终值。