How to efficiently de-interleave bits (inverse Morton)

后端 未结 5 1074
情歌与酒
情歌与酒 2020-12-05 03:15

This question: How to de-interleave bits (UnMortonizing?) has a good answer for extracting one of the two halves of a Morton number (just the odd bits), but I need a solutio

5条回答
  •  一向
    一向 (楼主)
    2020-12-05 03:53

    If you need speed than you can use table-lookup for one byte conversion at once (two bytes table is faster but to big). Procedure is made under Delphi IDE but the assembler/algorithem is the same.

    const
      MortonTableLookup : array[byte] of byte = ($00, $01, $10, $11, $12, ... ;
    
    procedure DeinterleaveBits(Input: cardinal);
    //In: eax
    //Out: dx = EvenBits; ax = OddBits;
    asm
      movzx   ecx, al                                     //Use 0th byte
      mov     dl, byte ptr[MortonTableLookup + ecx]
    //
      shr     eax, 8
      movzx   ecx, ah                                     //Use 2th byte
      mov     dh, byte ptr[MortonTableLookup + ecx]
    //
      shl     edx, 16
      movzx   ecx, al                                     //Use 1th byte
      mov     dl, byte ptr[MortonTableLookup + ecx]
    //
      shr     eax, 8
      movzx   ecx, ah                                     //Use 3th byte
      mov     dh, byte ptr[MortonTableLookup + ecx]
    //
      mov     ecx, edx  
      and     ecx, $F0F0F0F0
      mov     eax, ecx
      rol     eax, 12
      or      eax, ecx
    
      rol     edx, 4
      and     edx, $F0F0F0F0
      mov     ecx, edx
      rol     ecx, 12
      or      edx, ecx
    end;
    

提交回复
热议问题