DMD now incorporates a disassembler

max haughton maxhaton at gmail.com
Sat Jan 8 20:50:56 UTC 2022


On Saturday, 8 January 2022 at 18:47:11 UTC, Vladimir Marchevsky 
wrote:
> On Friday, 7 January 2022 at 21:41:55 UTC, Walter Bright wrote:
>> Compile with -vasm to see it! Enjoy!
>
> Any practical reason to put disassembler into compiler instead 
> of making it a separate tool?  Any ETA for renaming it into DMD 
> Burning ROM? :)

Most other compilers have been able to do this for years. The 
only difference is that the way the dmd backend is designed 
basically means that it never knows the instructions in a given 
basic block until they are actually emitted, so it has to 
disassemble it's own output rather than printing it's internal 
representation with (say) Intel assembly syntax.

See https://llvm.org/doxygen/classllvm_1_1MachineInstr.html from 
LLVM

GCC actually *only* uses an assembler to build object files. It 
doesn't have a distinct IR like LLVM does but the final stage of 
the RTL is basically a 1:1 representation of the instruction set:

```d
void phoneHome(size_t);
auto getLen(int[] arr)
{
     phoneHome(arr.length);
     return arr.length;
}
```
ends up as
```
;; Function getLen (_D7example6getLenFAiZm, funcdef_no=0, 
decl_uid=1395, cgraph_uid=2, symbol_order=1)

(note 1 0 37 NOTE_INSN_DELETED)
(note 37 1 8 (var_location arr (parallel [
         (expr_list:REG_DEP_TRUE (reg:DI 5 di [ arr ])
             (const_int 0 [0]))
         (expr_list:REG_DEP_TRUE (reg:DI 4 si [ arr+8 ])
             (const_int 8 [0x8]))
     ])) NOTE_INSN_VAR_LOCATION)
(note 8 37 7 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
(note 7 8 26 2 NOTE_INSN_FUNCTION_BEG)
(insn/f:TI 26 7 27 2 (set (mem:DI (pre_dec:DI (reg/f:DI 7 sp)) [0 
  S8 A8])
         (reg:DI 3 bx)) "/app/example.d":2:6 54 {*pushdi2_rex64}
      (expr_list:REG_DEAD (reg:DI 3 bx)
         (nil)))
(note 27 26 2 2 NOTE_INSN_PROLOGUE_END)
(insn 2 27 38 2 (set (reg:DI 3 bx [orig:85 arr ] [85])
         (reg:DI 5 di [92])) "/app/example.d":2:6 80 
{*movdi_internal}
      (nil))
(note 38 2 13 2 (var_location arr (reg:TI 3 bx [orig:85 arr ] 
[85])) NOTE_INSN_VAR_LOCATION)
(call_insn:TI 13 38 39 2 (call (mem:QI (symbol_ref:DI 
("_D7example9phoneHomeFmZv") [flags 0x41]  <function_decl 
0x7f491d317600 phoneHome>) [0 phoneHome S1 A8])
         (const_int 0 [0])) "/app/example.d":4:14 886 {*call}
      (expr_list:REG_CALL_ARG_LOCATION (nil)
         (expr_list:REG_DEAD (reg:DI 5 di)
             (expr_list:REG_CALL_DECL (symbol_ref:DI 
("_D7example9phoneHomeFmZv") [flags 0x41]  <function_decl 
0x7f491d317600 phoneHome>)
                 (nil))))
     (expr_list:DI (use (reg:DI 5 di))
         (nil)))
(note/c 39 13 17 2 (var_location arr (nil)) 
NOTE_INSN_VAR_LOCATION)
(insn 17 39 36 2 (set (reg/i:DI 0 ax)
         (reg:DI 3 bx [orig:85 arr ] [85])) "/app/example.d":6:1 
80 {*movdi_internal}
      (expr_list:REG_DEAD (reg:DI 3 bx [orig:85 arr ] [85])
         (nil)))
(note 36 17 29 2 NOTE_INSN_EPILOGUE_BEG)
(insn/f 29 36 40 2 (set (reg:DI 3 bx)
         (mem:DI (post_inc:DI (reg/f:DI 7 sp)) [0  S8 A8])) 
"/app/example.d":6:1 62 {*popdi1}
      (expr_list:REG_CFA_ADJUST_CFA (set (reg/f:DI 7 sp)
             (plus:DI (reg/f:DI 7 sp)
                 (const_int 8 [0x8])))
         (nil)))
(note 40 29 18 2 (var_location arr (nil) [uninit]) 
NOTE_INSN_VAR_LOCATION)
(insn 18 40 30 2 (use (reg/i:DI 0 ax)) "/app/example.d":6:1 -1
      (nil))
(jump_insn:TI 30 18 33 2 (simple_return) "/app/example.d":6:1 910 
{simple_return_internal}
      (nil)
  -> simple_return)
(barrier 33 30 25)
(note 25 33 0 NOTE_INSN_DELETED)
```
just prior to spitting it out for the assembler to process.


More information about the Digitalmars-d-announce mailing list