0xAA55 发表于 2018-5-6 04:56:01

【C】记一次GCC -O3优化效果实测

先上源码。



_sw_transceive是重点。我在调试STM32F103单片机SPI外设的时候遇到了问题,它并不能成功驱动我的硬件。为了排除外设操作的问题,我用自己写GPIO的方式实现了强行SPI协议传输,来看看传输的调用是不是对的。
这个函数本身很简短,就是模拟SPI外设的工作效果。通过拨弄SCK针来控制时间,然后写MOSI,读MISO。这个函数只有55行,但它用短循环调用了很多宏和static函数。

static uint32_t _sw_transceive(spi_master_ctrl_p smc, uint32_t txval)
{
        int bitcount = smc->dff ? 16 : 8;
        int togo = bitcount;
        uint32_t rxval = 0;
        if(!smc->bitorder) txval = _bit_reorder(txval, bitcount);
        if(smc->cpha)
        {
                if(smc->cpol)
                {
                        while(togo --> 0)
                        {
                                _sw_clk_l(smc);
                                _sw_mosi_out(smc, txval & 1); txval >>= 1;
                                _sw_clk_h(smc);
                                rxval = (rxval << 1) | _sw_miso_in(smc);
                        }
                }
                else
                {
                        while(togo --> 0)
                        {
                                _sw_clk_h(smc);
                                _sw_mosi_out(smc, txval & 1); txval >>= 1;
                                _sw_clk_l(smc);
                                rxval = (rxval << 1) | _sw_miso_in(smc);
                        }
                }
        }
        else
        {
                if(smc->cpol)
                {
                        while(togo --> 0)
                        {
                                rxval = (rxval << 1) | _sw_miso_in(smc);
                                _sw_mosi_out(smc, txval & 1); txval >>= 1;
                                _sw_clk_l(smc);
                                _sw_clk_h(smc);
                        }
                }
                else
                {
                        while(togo --> 0)
                        {
                                rxval = (rxval << 1) | _sw_miso_in(smc);
                                _sw_mosi_out(smc, txval & 1); txval >>= 1;
                                _sw_clk_h(smc);
                                _sw_clk_l(smc);
                        }
                }
        }
        if(smc->bitorder) rxval = _bit_reorder(rxval, bitcount);
        return rxval;
}熟悉STM32或SPI协议(以及它在STM32的外设接口)的人都能看出我这个函数是在干啥。



然而当我把它编译出来后,得到的二进制明显相当大——虽然是预料之内。至少直接写外设或者通过bit band写外设都是需要进行绝对地址直接寻址的,而且根据SPI的配置,这里存在这样几个变化的情况:[*]传输单位,是以8bit为单位还是16bit为单位(虽然16bit也不过是一次传输两个8bit而已)
[*]时钟相位CPHA,时钟先变化还是数据先变化
[*]时钟极性CPOL,高电平为闲置还是低电平为闲置
[*]位顺序,高位在前还是低位在前
按照GCC的优化能力,它会把不同的情况组合都拆开,并且会把短循环直接展开。那么我们得到的二进制是什么样的呢?请看IDA图表。



这简直有点复杂……
底下这些小格子是怎么回事呢?



说实话我看不懂。我对ARM汇编不熟。
顺手F5一下看看。



简直好多局部变量,而且后面也是各种“缩进拳”,完全和我写的源代码不一样。GCC的各种逻辑优化和循环展开已经把它变得面目全非了。

unsigned int __fastcall sw_transceive(int a1, unsigned int a2)
{
__int64 v2; // kr00_8
int v3; // r2
unsigned int v4; // r3
signed int v5; // r4
int v6; // r2
int v7; // r6
int v8; // r4
int v9; // lr
int v10; // r2
int v11; // r7
int v12; // r12
int v13; // r10
int v14; // r6
int v15; // r11
signed int v16; // r0
_BOOL4 v17; // r11
signed int v18; // r10
_BOOL4 v19; // r0
signed int v20; // r0
signed int v21; // r3
signed int v22; // r0
signed int v23; // r3
int v24; // r0
signed int v25; // r5
_BOOL4 v26; // r0
signed int v27; // r3
int v28; // r10
signed int v29; // r11
unsigned int result; // r0
unsigned int v31; // r1
unsigned int v32; // r2
unsigned int v33; // r2
unsigned int v34; // r2
unsigned int v35; // r2
unsigned int v36; // r2
unsigned int v37; // r2
unsigned int v38; // r2
unsigned int v39; // r3
int v40; // r11
int v41; // r10
int v42; // r9
int v43; // lr
int v44; // r4
int v45; // r12
int v46; // r2
int v47; // r7
int v48; // r3
signed int v49; // r10
int v50; // r11
signed int v51; // r9
signed int v52; // r5
_BOOL4 v53; // r11
signed int v54; // r0
signed int v55; // r9
signed int v56; // r0
_BOOL4 v57; // r9
int v58; // r10
int v59; // r9
int v60; // r0
_BOOL4 v61; // r10
_BOOL4 v62; // r9
signed int v63; // r11
_BOOL4 v64; // r10
_BOOL4 v65; // r10
_BOOL4 v66; // r10
_BOOL4 v67; // r10
_BOOL4 v68; // r10
_BOOL4 v69; // r10
_BOOL4 v70; // r10
unsigned int v71; // r1
_BOOL4 v72; // r3
int v73; // r3
unsigned int v74; // r2
unsigned int v75; // r2
unsigned int v76; // r2
unsigned int v77; // r2
int v78; // r2
unsigned int v79; // r3
unsigned int v80; // r3
unsigned int v81; // r0
int v82; // r6
int v83; // lr
int v84; // r4
int v85; // r3
int v86; // r12
int v87; // r9
int v88; // r7
int v89; // r10
int v90; // r11
signed int v91; // r9
_BOOL4 v92; // r10
_BOOL4 v93; // r11
bool v94; // zf
signed int v95; // r5
signed int v96; // r9
signed int v97; // r0
signed int v98; // r9
signed int v99; // r0
signed int v100; // r0
signed int v101; // r9
int v102; // r9
_BOOL4 v103; // r9
signed int v104; // r11
unsigned int v105; // r1
signed int v106; // r3
int v107; // lr
int v108; // r6
int v109; // r12
int v110; // r4
int v111; // r7
int v112; // r3
signed int v113; // r10
int v114; // r11
signed int v115; // r9
signed int v116; // r5
_BOOL4 v117; // r11
signed int v118; // r0
signed int v119; // r9
signed int v120; // r0
_BOOL4 v121; // r9
int v122; // r10
int v123; // r9
int v124; // r0
_BOOL4 v125; // r10
_BOOL4 v126; // r9
signed int v127; // r11
_BOOL4 v128; // r10
_BOOL4 v129; // r10
_BOOL4 v130; // r10
_BOOL4 v131; // r10
_BOOL4 v132; // r10
_BOOL4 v133; // r10
_BOOL4 v134; // r10
unsigned int v135; // r1
_BOOL4 v136; // r3
signed int v137; //
int v138; //
_BOOL4 v139; //
int v140; //
signed int v141; //
signed int v142; //
signed int v143; //
signed int v144; //
signed int v145; //
signed int v146; //
signed int v147; //
signed int v148; //
_BOOL4 v149; //
signed int v150; //
_BOOL4 v151; //

v2 = *(_QWORD *)(a1 + 24);
v138 = *(_QWORD *)(a1 + 24) >> 32;
if ( !(_DWORD)v2 )
{
    if ( HIDWORD(v2) )
    {
      v137 = 7;
      goto LABEL_6;
    }
    v3 = a2 & 1;
    v4 = a2 >> 1;
    v5 = 6;
    v137 = 7;
LABEL_30:
    a2 = (v4 >> 6) & 1 | 2
                     * ((v4 >> 5) & 1 | 2
                                        * ((v4 >> 4) & 1 | 2
                                                         * ((v4 >> 3) & 1 | 2
                                                                        * ((v4 >> 2) & 1 | 2
                                                                                           * ((v4 >> 1) & 1 | 2 * (v4 & 1 | 2 * v3))))));
    v32 = v4 >> 7;
    if ( v5 != 6 )
    {
      a2 = v32 & 1 | 2 * a2;
      v33 = v4 >> 8;
      if ( v5 > 7 )
      {
      a2 = v33 & 1 | 2 * a2;
      v34 = v4 >> 9;
      if ( v5 > 8 )
      {
          a2 = v34 & 1 | 2 * a2;
          v35 = v4 >> 10;
          if ( v5 > 9 )
          {
            a2 = v35 & 1 | 2 * a2;
            v36 = v4 >> 11;
            if ( v5 > 10 )
            {
            a2 = v36 & 1 | 2 * a2;
            v37 = v4 >> 12;
            if ( v5 > 11 )
            {
                a2 = v37 & 1 | 2 * a2;
                v38 = v4 >> 13;
                if ( v5 > 12 )
                {
                  a2 = v38 & 1 | 2 * a2;
                  v39 = v4 >> 14;
                  if ( v5 == 14 )
                  a2 = v39 | 2 * a2;
                }
            }
            }
          }
      }
      }
    }
LABEL_6:
    v7 = *(_QWORD *)(a1 + 16) >> 32;
    v6 = *(_QWORD *)(a1 + 16);
    if ( v7 )
      goto LABEL_7;
    goto LABEL_40;
}
if ( !HIDWORD(v2) )
{
    v3 = a2 & 1;
    v4 = a2 >> 1;
    v5 = 14;
    v137 = 15;
    goto LABEL_30;
}
v7 = *(_QWORD *)(a1 + 16) >> 32;
v6 = *(_QWORD *)(a1 + 16);
v137 = 15;
if ( v7 )
{
LABEL_7:
    if ( v6 )
    {
      v8 = *(unsigned __int16 *)(a1 + 6);
      v9 = *(unsigned __int16 *)(a1 + 10);
      v10 = (*(unsigned __int16 *)(a1 + 4) << 15) + 1109459328;
      v11 = (*(unsigned __int16 *)(a1 + 8) << 15) + 1109459328;
      v12 = *(unsigned __int16 *)(a1 + 14);
      v13 = *(unsigned __int16 *)(a1 + 12) << 15;
      *(_DWORD *)(v10 + 4 * v8) = 0;
      v14 = v13 + 1109459200;
      *(_DWORD *)(v11 + 4 * v9) = a2 & 1;
      *(_DWORD *)(v10 + 4 * v8) = 1;
      v15 = *(_DWORD *)(v13 + 1109459200 + 4 * v12);
      *(_DWORD *)(v10 + 4 * v8) = 0;
      *(_DWORD *)(v11 + 4 * v9) = (a2 >> 1) & 1;
      *(_DWORD *)(v10 + 4 * v8) = 1;
      v16 = *(_DWORD *)(v13 + 1109459200 + 4 * v12);
      *(_DWORD *)(v10 + 4 * v8) = 0;
      *(_DWORD *)(v11 + 4 * v9) = (a2 >> 2) & 1;
      *(_DWORD *)(v10 + 4 * v8) = 1;
      v17 = v15 != 0;
      v18 = v16;
      if ( v16 )
      v18 = 1;
      v19 = *(_DWORD *)(v14 + 4 * v12) != 0;
      *(_DWORD *)(v10 + 4 * v8) = 0;
      *(_DWORD *)(v11 + 4 * v9) = (a2 >> 3) & 1;
      *(_DWORD *)(v10 + 4 * v8) = 1;
      v139 = v19;
      v20 = *(_DWORD *)(v14 + 4 * v12);
      *(_DWORD *)(v10 + 4 * v8) = 0;
      *(_DWORD *)(v11 + 4 * v9) = (a2 >> 4) & 1;
      v21 = v20;
      if ( v20 )
      v21 = 1;
      *(_DWORD *)(v10 + 4 * v8) = 1;
      v22 = *(_DWORD *)(v14 + 4 * v12);
      v141 = v21;
      *(_DWORD *)(v10 + 4 * v8) = 0;
      *(_DWORD *)(v11 + 4 * v9) = (a2 >> 5) & 1;
      v23 = v22;
      if ( v22 )
      v23 = 1;
      *(_DWORD *)(v10 + 4 * v8) = 1;
      v145 = v23;
      v24 = *(_DWORD *)(v14 + 4 * v12);
      *(_DWORD *)(v10 + 4 * v8) = 0;
      *(_DWORD *)(v11 + 4 * v9) = (a2 >> 6) & 1;
      *(_DWORD *)(v10 + 4 * v8) = 1;
      v25 = *(_DWORD *)(v14 + 4 * v12);
      *(_DWORD *)(v10 + 4 * v8) = 0;
      *(_DWORD *)(v11 + 4 * v9) = (a2 >> 7) & 1;
      *(_DWORD *)(v10 + 4 * v8) = 1;
      v26 = v24 != 0;
      v27 = v25;
      if ( v25 )
      v27 = 1;
      v28 = v18 | 2 * v17;
      v29 = *(_DWORD *)(v14 + 4 * v12);
      if ( *(_DWORD *)(v14 + 4 * v12) )
      v29 = 1;
      result = v29 | 2 * (v27 | 2 * (v26 | 2 * (v145 | 2 * (v141 | 2 * (v139 | 2 * v28)))));
      if ( v137 != 7 )
      {
      *(_DWORD *)(v10 + 4 * v8) = 0;
      *(_DWORD *)(v11 + 4 * v9) = (unsigned __int8)a2 >> 8;
      *(_DWORD *)(v10 + 4 * v8) = 1;
      result = (*(_DWORD *)(v14 + 4 * v12) != 0) | 2 * result;
      if ( v137 > 8 )
      {
          *(_DWORD *)(v10 + 4 * v8) = 0;
          *(_DWORD *)(v11 + 4 * v9) = (a2 >> 9) & 1;
          *(_DWORD *)(v10 + 4 * v8) = 1;
          result = (*(_DWORD *)(v14 + 4 * v12) != 0) | 2 * result;
          if ( v137 > 9 )
          {
            *(_DWORD *)(v10 + 4 * v8) = 0;
            *(_DWORD *)(v11 + 4 * v9) = (a2 >> 10) & 1;
            *(_DWORD *)(v10 + 4 * v8) = 1;
            result = (*(_DWORD *)(v14 + 4 * v12) != 0) | 2 * result;
            if ( v137 > 10 )
            {
            *(_DWORD *)(v10 + 4 * v8) = 0;
            *(_DWORD *)(v11 + 4 * v9) = (a2 >> 11) & 1;
            *(_DWORD *)(v10 + 4 * v8) = 1;
            result = (*(_DWORD *)(v14 + 4 * v12) != 0) | 2 * result;
            if ( v137 > 11 )
            {
                *(_DWORD *)(v10 + 4 * v8) = 0;
                *(_DWORD *)(v11 + 4 * v9) = (a2 >> 12) & 1;
                *(_DWORD *)(v10 + 4 * v8) = 1;
                result = (*(_DWORD *)(v14 + 4 * v12) != 0) | 2 * result;
                if ( v137 > 12 )
                {
                  *(_DWORD *)(v10 + 4 * v8) = 0;
                  *(_DWORD *)(v11 + 4 * v9) = (a2 >> 13) & 1;
                  *(_DWORD *)(v10 + 4 * v8) = 1;
                  result = (*(_DWORD *)(v14 + 4 * v12) != 0) | 2 * result;
                  if ( v137 > 13 )
                  {
                  *(_DWORD *)(v10 + 4 * v8) = 0;
                  *(_DWORD *)(v11 + 4 * v9) = (a2 >> 14) & 1;
                  *(_DWORD *)(v10 + 4 * v8) = 1;
                  v31 = a2 >> 15;
                  result = (*(_DWORD *)(v14 + 4 * v12) != 0) | 2 * result;
                  if ( v137 == 15 )
                  {
                      *(_DWORD *)(v10 + 4 * v8) = 0;
                      *(_DWORD *)(v11 + 4 * v9) = v31;
                      *(_DWORD *)(v10 + 4 * v8) = 1;
                      result = (*(_DWORD *)(v14 + 4 * v12) != 0) | 2 * result;
                  }
                  }
                }
            }
            }
          }
      }
      }
    }
    else
    {
      v82 = *(unsigned __int16 *)(a1 + 6);
      v83 = *(unsigned __int16 *)(a1 + 10);
      v84 = (*(unsigned __int16 *)(a1 + 4) << 15) + 1109459328;
      v85 = (*(unsigned __int16 *)(a1 + 8) << 15) + 1109459328;
      v86 = *(unsigned __int16 *)(a1 + 14);
      v87 = *(unsigned __int16 *)(a1 + 12) << 15;
      *(_DWORD *)(v84 + 4 * v82) = 1;
      v88 = v87 + 1109459200;
      *(_DWORD *)(v85 + 4 * v83) = a2 & 1;
      *(_DWORD *)(v84 + 4 * v82) = 0;
      v89 = *(_DWORD *)(v87 + 1109459200 + 4 * v86);
      *(_DWORD *)(v84 + 4 * v82) = 1;
      *(_DWORD *)(v85 + 4 * v83) = (a2 >> 1) & 1;
      *(_DWORD *)(v84 + 4 * v82) = 0;
      v90 = *(_DWORD *)(v87 + 1109459200 + 4 * v86);
      *(_DWORD *)(v84 + 4 * v82) = 1;
      *(_DWORD *)(v85 + 4 * v83) = (a2 >> 2) & 1;
      *(_DWORD *)(v84 + 4 * v82) = 0;
      v91 = *(_DWORD *)(v87 + 1109459200 + 4 * v86);
      *(_DWORD *)(v84 + 4 * v82) = 1;
      v92 = v89 != 0;
      *(_DWORD *)(v85 + 4 * v83) = (a2 >> 3) & 1;
      *(_DWORD *)(v84 + 4 * v82) = 0;
      v93 = v90 != 0;
      v95 = v91;
      v94 = v91 == 0;
      v96 = *(_DWORD *)(v88 + 4 * v86);
      *(_DWORD *)(v84 + 4 * v82) = 1;
      if ( !v94 )
      v95 = 1;
      *(_DWORD *)(v85 + 4 * v83) = (a2 >> 4) & 1;
      v97 = v96;
      if ( v96 )
      v97 = 1;
      *(_DWORD *)(v84 + 4 * v82) = 0;
      v98 = *(_DWORD *)(v88 + 4 * v86);
      v143 = v97;
      *(_DWORD *)(v84 + 4 * v82) = 1;
      *(_DWORD *)(v85 + 4 * v83) = (a2 >> 5) & 1;
      v99 = v98;
      if ( v98 )
      v99 = 1;
      *(_DWORD *)(v84 + 4 * v82) = 0;
      v147 = v99;
      v100 = *(_DWORD *)(v88 + 4 * v86);
      *(_DWORD *)(v84 + 4 * v82) = 1;
      v101 = v100;
      if ( v100 )
      v101 = 1;
      *(_DWORD *)(v85 + 4 * v83) = (a2 >> 6) & 1;
      *(_DWORD *)(v84 + 4 * v82) = 0;
      v150 = v101;
      v102 = *(_DWORD *)(v88 + 4 * v86);
      *(_DWORD *)(v84 + 4 * v82) = 1;
      *(_DWORD *)(v85 + 4 * v83) = (a2 >> 7) & 1;
      *(_DWORD *)(v84 + 4 * v82) = 0;
      v140 = v93 | 2 * v92;
      v103 = v102 != 0;
      v104 = *(_DWORD *)(v88 + 4 * v86);
      if ( *(_DWORD *)(v88 + 4 * v86) )
      v104 = 1;
      result = v104 | 2 * (v103 | 2 * (v150 | 2 * (v147 | 2 * (v143 | 2 * (v95 | 2 * v140)))));
      if ( v137 != 7 )
      {
      *(_DWORD *)(v84 + 4 * v82) = 1;
      *(_DWORD *)(v85 + 4 * v83) = (unsigned __int8)a2 >> 8;
      *(_DWORD *)(v84 + 4 * v82) = 0;
      result = (*(_DWORD *)(v88 + 4 * v86) != 0) | 2 * result;
      if ( v137 > 8 )
      {
          *(_DWORD *)(v84 + 4 * v82) = 1;
          *(_DWORD *)(v85 + 4 * v83) = (a2 >> 9) & 1;
          *(_DWORD *)(v84 + 4 * v82) = 0;
          result = (*(_DWORD *)(v88 + 4 * v86) != 0) | 2 * result;
          if ( v137 > 9 )
          {
            *(_DWORD *)(v84 + 4 * v82) = 1;
            *(_DWORD *)(v85 + 4 * v83) = (a2 >> 10) & 1;
            *(_DWORD *)(v84 + 4 * v82) = 0;
            result = (*(_DWORD *)(v88 + 4 * v86) != 0) | 2 * result;
            if ( v137 > 10 )
            {
            *(_DWORD *)(v84 + 4 * v82) = 1;
            *(_DWORD *)(v85 + 4 * v83) = (a2 >> 11) & 1;
            *(_DWORD *)(v84 + 4 * v82) = 0;
            result = (*(_DWORD *)(v88 + 4 * v86) != 0) | 2 * result;
            if ( v137 > 11 )
            {
                *(_DWORD *)(v84 + 4 * v82) = 1;
                *(_DWORD *)(v85 + 4 * v83) = (a2 >> 12) & 1;
                *(_DWORD *)(v84 + 4 * v82) = 0;
                result = (*(_DWORD *)(v88 + 4 * v86) != 0) | 2 * result;
                if ( v137 > 12 )
                {
                  *(_DWORD *)(v84 + 4 * v82) = 1;
                  *(_DWORD *)(v85 + 4 * v83) = (a2 >> 13) & 1;
                  *(_DWORD *)(v84 + 4 * v82) = 0;
                  result = (*(_DWORD *)(v88 + 4 * v86) != 0) | 2 * result;
                  if ( v137 > 13 )
                  {
                  *(_DWORD *)(v84 + 4 * v82) = 1;
                  *(_DWORD *)(v85 + 4 * v83) = (a2 >> 14) & 1;
                  *(_DWORD *)(v84 + 4 * v82) = 0;
                  v105 = a2 >> 15;
                  result = (*(_DWORD *)(v88 + 4 * v86) != 0) | 2 * result;
                  if ( v137 == 15 )
                  {
                      *(_DWORD *)(v84 + 4 * v82) = 1;
                      *(_DWORD *)(v85 + 4 * v83) = v105;
                      *(_DWORD *)(v84 + 4 * v82) = 0;
                      v106 = *(_DWORD *)(v88 + 4 * v86);
                      if ( *(_DWORD *)(v88 + 4 * v86) )
                        v106 = 1;
                      result = v106 | 2 * result;
                  }
                  }
                }
            }
            }
          }
      }
      }
    }
    goto LABEL_27;
}
LABEL_40:
v40 = *(unsigned __int16 *)(a1 + 12);
v41 = *(unsigned __int16 *)(a1 + 8);
v42 = *(unsigned __int16 *)(a1 + 4);
if ( v6 )
{
    v43 = *(unsigned __int16 *)(a1 + 14);
    v44 = *(unsigned __int16 *)(a1 + 6);
    v45 = *(unsigned __int16 *)(a1 + 10);
    v46 = (v42 << 15) + 1109459328;
    v47 = (v41 << 15) + 1109459328;
    v48 = (v40 << 15) + 1109459200;
    v49 = *(_DWORD *)((v40 << 15) + 0x42210100 + 4 * v43);
    *(_DWORD *)(v47 + 4 * v45) = a2 & 1;
    *(_DWORD *)(v46 + 4 * v44) = v7;
    *(_DWORD *)(v46 + 4 * v44) = 1;
    v50 = *(_DWORD *)((v40 << 15) + 0x42210100 + 4 * v43);
    *(_DWORD *)(v47 + 4 * v45) = (a2 >> 1) & 1;
    *(_DWORD *)(v46 + 4 * v44) = v7;
    *(_DWORD *)(v46 + 4 * v44) = 1;
    v51 = *(_DWORD *)(v48 + 4 * v43);
    v52 = v49;
    if ( v49 )
      v52 = 1;
    *(_DWORD *)(v47 + 4 * v45) = (a2 >> 2) & 1;
    v53 = v50 != 0;
    v54 = v51;
    if ( v51 )
      v54 = 1;
    *(_DWORD *)(v46 + 4 * v44) = v7;
    *(_DWORD *)(v46 + 4 * v44) = 1;
    v55 = *(_DWORD *)(v48 + 4 * v43);
    *(_DWORD *)(v47 + 4 * v45) = (a2 >> 3) & 1;
    v142 = v54;
    *(_DWORD *)(v46 + 4 * v44) = v7;
    v56 = v55;
    *(_DWORD *)(v46 + 4 * v44) = 1;
    if ( v55 )
      v56 = 1;
    v57 = *(_DWORD *)(v48 + 4 * v43) != 0;
    v146 = v56;
    *(_DWORD *)(v47 + 4 * v45) = (a2 >> 4) & 1;
    *(_DWORD *)(v46 + 4 * v44) = v7;
    *(_DWORD *)(v46 + 4 * v44) = 1;
    v58 = *(_DWORD *)(v48 + 4 * v43);
    *(_DWORD *)(v47 + 4 * v45) = (a2 >> 5) & 1;
    *(_DWORD *)(v46 + 4 * v44) = v7;
    *(_DWORD *)(v46 + 4 * v44) = 1;
    v149 = v57;
    v59 = *(_DWORD *)(v48 + 4 * v43);
    *(_DWORD *)(v47 + 4 * v45) = (a2 >> 6) & 1;
    *(_DWORD *)(v46 + 4 * v44) = v7;
    *(_DWORD *)(v46 + 4 * v44) = 1;
    v60 = v53 | 2 * v52;
    v61 = v58 != 0;
    v62 = v59 != 0;
    v63 = *(_DWORD *)(v48 + 4 * v43);
    if ( *(_DWORD *)(v48 + 4 * v43) )
      v63 = 1;
    *(_DWORD *)(v47 + 4 * v45) = (a2 >> 7) & 1;
    result = v63 | 2 * (v62 | 2 * (v61 | 2 * (v149 | 2 * (v146 | 2 * (v142 | 2 * v60)))));
    *(_DWORD *)(v46 + 4 * v44) = v7;
    *(_DWORD *)(v46 + 4 * v44) = 1;
    if ( v137 != 7 )
    {
      v64 = *(_DWORD *)(v48 + 4 * v43) != 0;
      *(_DWORD *)(v47 + 4 * v45) = (unsigned __int8)a2 >> 8;
      result = v64 | 2 * result;
      *(_DWORD *)(v46 + 4 * v44) = v7;
      *(_DWORD *)(v46 + 4 * v44) = 1;
      if ( v137 > 8 )
      {
      v65 = *(_DWORD *)(v48 + 4 * v43) != 0;
      *(_DWORD *)(v47 + 4 * v45) = (a2 >> 9) & 1;
      result = v65 | 2 * result;
      *(_DWORD *)(v46 + 4 * v44) = v7;
      *(_DWORD *)(v46 + 4 * v44) = 1;
      if ( v137 > 9 )
      {
          v66 = *(_DWORD *)(v48 + 4 * v43) != 0;
          *(_DWORD *)(v47 + 4 * v45) = (a2 >> 10) & 1;
          result = v66 | 2 * result;
          *(_DWORD *)(v46 + 4 * v44) = v7;
          *(_DWORD *)(v46 + 4 * v44) = 1;
          if ( v137 > 10 )
          {
            v67 = *(_DWORD *)(v48 + 4 * v43) != 0;
            *(_DWORD *)(v47 + 4 * v45) = (a2 >> 11) & 1;
            result = v67 | 2 * result;
            *(_DWORD *)(v46 + 4 * v44) = v7;
            *(_DWORD *)(v46 + 4 * v44) = 1;
            if ( v137 > 11 )
            {
            v68 = *(_DWORD *)(v48 + 4 * v43) != 0;
            *(_DWORD *)(v47 + 4 * v45) = (a2 >> 12) & 1;
            result = v68 | 2 * result;
            *(_DWORD *)(v46 + 4 * v44) = v7;
            *(_DWORD *)(v46 + 4 * v44) = 1;
            if ( v137 > 12 )
            {
                v69 = *(_DWORD *)(v48 + 4 * v43) != 0;
                *(_DWORD *)(v47 + 4 * v45) = (a2 >> 13) & 1;
                result = v69 | 2 * result;
                *(_DWORD *)(v46 + 4 * v44) = v7;
                *(_DWORD *)(v46 + 4 * v44) = 1;
                if ( v137 > 13 )
                {
                  v70 = *(_DWORD *)(v48 + 4 * v43) != 0;
                  *(_DWORD *)(v47 + 4 * v45) = (a2 >> 14) & 1;
                  v71 = a2 >> 15;
                  *(_DWORD *)(v46 + 4 * v44) = v7;
                  result = v70 | 2 * result;
                  *(_DWORD *)(v46 + 4 * v44) = 1;
                  if ( v137 == 15 )
                  {
                  v72 = *(_DWORD *)(v48 + 4 * v43) != 0;
                  *(_DWORD *)(v47 + 4 * v45) = v71;
                  result = v72 | 2 * result;
                  *(_DWORD *)(v46 + 4 * v44) = 0;
                  *(_DWORD *)(v46 + 4 * v44) = 1;
                  }
                }
            }
            }
          }
      }
      }
    }
}
else
{
    v107 = *(unsigned __int16 *)(a1 + 14);
    v108 = *(unsigned __int16 *)(a1 + 6);
    v109 = *(unsigned __int16 *)(a1 + 10);
    v110 = (v42 << 15) + 1109459328;
    v111 = (v41 << 15) + 1109459328;
    v112 = (v40 << 15) + 1109459200;
    v113 = *(_DWORD *)((v40 << 15) + 0x42210100 + 4 * v107);
    *(_DWORD *)(v111 + 4 * v109) = a2 & 1;
    *(_DWORD *)(v110 + 4 * v108) = 1;
    *(_DWORD *)(v110 + 4 * v108) = 0;
    v114 = *(_DWORD *)((v40 << 15) + 0x42210100 + 4 * v107);
    *(_DWORD *)(v111 + 4 * v109) = (a2 >> 1) & 1;
    *(_DWORD *)(v110 + 4 * v108) = 1;
    *(_DWORD *)(v110 + 4 * v108) = 0;
    v115 = *(_DWORD *)(v112 + 4 * v107);
    v116 = v113;
    if ( v113 )
      v116 = 1;
    *(_DWORD *)(v111 + 4 * v109) = (a2 >> 2) & 1;
    v117 = v114 != 0;
    v118 = v115;
    if ( v115 )
      v118 = 1;
    *(_DWORD *)(v110 + 4 * v108) = 1;
    *(_DWORD *)(v110 + 4 * v108) = 0;
    v119 = *(_DWORD *)(v112 + 4 * v107);
    *(_DWORD *)(v111 + 4 * v109) = (a2 >> 3) & 1;
    v144 = v118;
    *(_DWORD *)(v110 + 4 * v108) = 1;
    v120 = v119;
    *(_DWORD *)(v110 + 4 * v108) = 0;
    if ( v119 )
      v120 = 1;
    v121 = *(_DWORD *)(v112 + 4 * v107) != 0;
    v148 = v120;
    *(_DWORD *)(v111 + 4 * v109) = (a2 >> 4) & 1;
    *(_DWORD *)(v110 + 4 * v108) = 1;
    *(_DWORD *)(v110 + 4 * v108) = 0;
    v122 = *(_DWORD *)(v112 + 4 * v107);
    *(_DWORD *)(v111 + 4 * v109) = (a2 >> 5) & 1;
    *(_DWORD *)(v110 + 4 * v108) = 1;
    *(_DWORD *)(v110 + 4 * v108) = 0;
    v151 = v121;
    v123 = *(_DWORD *)(v112 + 4 * v107);
    *(_DWORD *)(v111 + 4 * v109) = (a2 >> 6) & 1;
    *(_DWORD *)(v110 + 4 * v108) = 1;
    *(_DWORD *)(v110 + 4 * v108) = 0;
    v124 = v117 | 2 * v116;
    v125 = v122 != 0;
    v126 = v123 != 0;
    v127 = *(_DWORD *)(v112 + 4 * v107);
    if ( *(_DWORD *)(v112 + 4 * v107) )
      v127 = 1;
    *(_DWORD *)(v111 + 4 * v109) = (a2 >> 7) & 1;
    result = v127 | 2 * (v126 | 2 * (v125 | 2 * (v151 | 2 * (v148 | 2 * (v144 | 2 * v124)))));
    *(_DWORD *)(v110 + 4 * v108) = 1;
    *(_DWORD *)(v110 + 4 * v108) = 0;
    if ( v137 != 7 )
    {
      v128 = *(_DWORD *)(v112 + 4 * v107) != 0;
      *(_DWORD *)(v111 + 4 * v109) = (unsigned __int8)a2 >> 8;
      result = v128 | 2 * result;
      *(_DWORD *)(v110 + 4 * v108) = 1;
      *(_DWORD *)(v110 + 4 * v108) = 0;
      if ( v137 > 8 )
      {
      v129 = *(_DWORD *)(v112 + 4 * v107) != 0;
      *(_DWORD *)(v111 + 4 * v109) = (a2 >> 9) & 1;
      result = v129 | 2 * result;
      *(_DWORD *)(v110 + 4 * v108) = 1;
      *(_DWORD *)(v110 + 4 * v108) = 0;
      if ( v137 > 9 )
      {
          v130 = *(_DWORD *)(v112 + 4 * v107) != 0;
          *(_DWORD *)(v111 + 4 * v109) = (a2 >> 10) & 1;
          result = v130 | 2 * result;
          *(_DWORD *)(v110 + 4 * v108) = 1;
          *(_DWORD *)(v110 + 4 * v108) = 0;
          if ( v137 > 10 )
          {
            v131 = *(_DWORD *)(v112 + 4 * v107) != 0;
            *(_DWORD *)(v111 + 4 * v109) = (a2 >> 11) & 1;
            result = v131 | 2 * result;
            *(_DWORD *)(v110 + 4 * v108) = 1;
            *(_DWORD *)(v110 + 4 * v108) = 0;
            if ( v137 > 11 )
            {
            v132 = *(_DWORD *)(v112 + 4 * v107) != 0;
            *(_DWORD *)(v111 + 4 * v109) = (a2 >> 12) & 1;
            result = v132 | 2 * result;
            *(_DWORD *)(v110 + 4 * v108) = 1;
            *(_DWORD *)(v110 + 4 * v108) = 0;
            if ( v137 > 12 )
            {
                v133 = *(_DWORD *)(v112 + 4 * v107) != 0;
                *(_DWORD *)(v111 + 4 * v109) = (a2 >> 13) & 1;
                result = v133 | 2 * result;
                *(_DWORD *)(v110 + 4 * v108) = 1;
                *(_DWORD *)(v110 + 4 * v108) = 0;
                if ( v137 > 13 )
                {
                  v134 = *(_DWORD *)(v112 + 4 * v107) != 0;
                  *(_DWORD *)(v111 + 4 * v109) = (a2 >> 14) & 1;
                  v135 = a2 >> 15;
                  *(_DWORD *)(v110 + 4 * v108) = 1;
                  result = v134 | 2 * result;
                  *(_DWORD *)(v110 + 4 * v108) = 0;
                  if ( v137 == 15 )
                  {
                  v136 = *(_DWORD *)(v112 + 4 * v107) != 0;
                  *(_DWORD *)(v111 + 4 * v109) = v135;
                  *(_DWORD *)(v110 + 4 * v108) = 1;
                  result = v136 | 2 * result;
                  *(_DWORD *)(v110 + 4 * v108) = 0;
                  }
                }
            }
            }
          }
      }
      }
    }
}
LABEL_27:
if ( v138 )
{
    v73 = (result >> 7) & 1 | 2
                            * ((result >> 6) & 1 | 2
                                                 * ((result >> 5) & 1 | 2
                                                                      * ((result >> 4) & 1 | 2
                                                                                           * ((result >> 3) & 1 | 2 * ((result >> 2) & 1 | 2 * (2 * result & 2 | (result >> 1) & 1))))));
    v74 = result >> 8;
    if ( v137 == 7
      || (v73 = v74 & 1 | 2 * v73, v75 = result >> 9, v137 <= 8)
      || (v73 = v75 & 1 | 2 * v73, v76 = result >> 10, v137 <= 9)
      || (v73 = v76 & 1 | 2 * v73, v77 = result >> 11, v137 <= 10) )
    {
      result = v73;
    }
    else
    {
      v78 = v77 & 1 | 2 * v73;
      v79 = result >> 12;
      if ( v137 <= 11
      || (v78 = v79 & 1 | 2 * v78, v80 = result >> 13, v137 <= 12)
      || (v78 = v80 & 1 | 2 * v78, v137 <= 13)
      || (v78 = (result >> 14) & 1 | 2 * v78, v81 = result >> 15, v137 != 15) )
      {
      result = v78;
      }
      else
      {
      result = v81 | 2 * v78;
      }
    }
}
return result;
}其实有些地方它并不是十分准确,因为我是不停地对一个volatile修饰的变量进行读写,而IDA的F5会把这些大量的volatile读写操作整理成一长句,或者搞没。所以不能太信任它。
ARM不同于牙膏厂x86,它没有缓存的概念,也没有乱序执行。而且因为ARM有个三级流水线,每次跳转都要浪费两个周期的时间,所以要尽量减少跳转的次数。
但该做成函数的还是要做成函数,如果啥都内联的话,STM32F103的64K ROM是不够用的。

Ayala 发表于 2018-5-6 08:12:41

每个循环单独写成一个函数就好 牺牲点性能没啥大不了的
现在arm被冷落了 大多开始转向risc-v了
https://en.wikipedia.org/wiki/RISC-V
页: [1]
查看完整版本: 【C】记一次GCC -O3优化效果实测