Studying note of GCC-3.4.6 source (70)

本文详细解析了编译器初始化过程中的关键步骤,包括创建虚拟函数上下文、初始化表达式等,并介绍了如何确定哪些寄存器可以直接用于内存读写操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.3.4. Finish compiler’s initialization

Back lang_dependent_init, it is happy to see the end of the function. The initialization of the compiler will be finished soon.

 

lang_dependent_init (continue)

 

4542   /* The following initialization functions need to generate rtl, so

4543     provide a dummy function context for them.  */

4544   init_dummy_function_start ();

4545   init_expr_once ();

4546   expand_dummy_function_end ();

4547

4548   /* If dbx symbol table desired, initialize writing it and output the

4549     predefined types.  */

4550   timevar_push (TV_SYMOUT);

4551

4552 #ifdef DWARF2_UNWIND_INFO

4553   if (dwarf2out_do_frame ())

4554     dwarf2out_frame_init ();

4555 #endif

4556

4557   /* Now we have the correct original filename, we can initialize

4558     debug output.  */

4559   (*debug_hooks->init) (name);

4560

4561   timevar_pop (TV_SYMOUT);

4562

4563   return 1;

4564 }

 

Here creating the dummy function context is not necessary, as we don’t indeed emit rtl instrucitons (call emit_insn). The purpose of init_expr_once is to set up which modes can be used directly in memory and to initialize the block move optab. To collect data, SET instruction is created for test. Notice that mem and mem1 should be carefully selected, either of one should be valid on any machine, otherwise incorrect result may gotten. Here men and mem1 are stack pointer and frame poiner respectively, then test storing and loading between memory they refer and register.

 

232  void

233  init_expr_once (void)                                                                                       in expr.c

234  {

235    rtx insn, pat;

236    enum machine_mode mode;

237    int num_clobbers;

238    rtx mem, mem1;

239    rtx reg;

240 

241    /* Try indexing by frame ptr and try by stack ptr.

242      It is known that on the Convex the stack ptr isn't a valid index.

243      With luck, one or the other is valid on any machine.  */

244    mem = gen_rtx_MEM (VOIDmode, stack_pointer_rtx);

245    mem1 = gen_rtx_MEM (VOIDmode, frame_pointer_rtx);

246 

247   /* A scratch register we can modify in-place below to avoid

248      useless RTL allocations.  */

249    reg = gen_rtx_REG (VOIDmode, -1);

250 

251    insn = rtx_alloc (INSN);

252    pat = gen_rtx_SET (0, NULL_RTX, NULL_RTX);

253    PATTERN (insn) = pat;

254 

255    for (mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;

256         mode = (enum machine_mode) ((int) mode + 1))

257    {

258      int regno;

259 

260      direct_load[(int) mode] = direct_store[(int) mode] = 0;

261      PUT_MODE (mem, mode);

262      PUT_MODE (mem1, mode);

263      PUT_MODE (reg, mode);

264 

265      /* See if there is some register that can be used in this mode and

266        directly loaded or stored from memory.  */

267 

268      if (mode != VOIDmode && mode != BLKmode)

269        for (regno = 0; regno < FIRST_PSEUDO_REGISTER

270            && (direct_load[(int) mode] == 0 || direct_store[(int) mode] == 0);

271            regno++)

272        {

273          if (!HARD_REGNO_MODE_OK (regno, mode))

274            continue;

275 

276          REGNO (reg) = regno;

277 

278              SET_SRC (pat) = mem;

279          SET_DEST (pat) = reg;

280           if (recog (pat, insn, &num_clobbers) >= 0)

281             direct_load[(int) mode] = 1;

282 

283           SET_SRC (pat) = mem1;

284           SET_DEST (pat) = reg;

285           if (recog (pat, insn, &num_clobbers) >= 0)

286             direct_load[(int) mode] = 1;

287 

288           SET_SRC (pat) = reg;

289           SET_DEST (pat) = mem;

290           if (recog (pat, insn, &num_clobbers) >= 0)

291             direct_store[(int) mode] = 1;

292 

293          SET_SRC (pat) = reg;

294           SET_DEST (pat) = mem1;

295           if (recog (pat, insn, &num_clobbers) >= 0)

296             direct_store[(int) mode] = 1;

297        }

298    }

299 

300    mem = gen_rtx_MEM (VOIDmode, gen_rtx_raw_REG (Pmode, 10000));

301 

302    for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;

303         mode = GET_MODE_WIDER_MODE (mode))

304    {

305      enum machine_mode srcmode;

306      for (srcmode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); srcmode != mode;

307          srcmode = GET_MODE_WIDER_MODE (srcmode))

308      {

309        enum insn_code ic;

310 

311         ic = can_extend_p (mode, srcmode, 0);

312        if (ic == CODE_FOR_nothing)

313          continue;

314 

315        PUT_MODE (mem, srcmode);

316 

317        if ((*insn_data[ic].operand[1].predicate) (mem, srcmode))

318          float_extend_from_mem[mode][srcmode] = true;

319      }

320    }

321  }

 

At line 273, HARD_REGNO_MODE_OK selects the real hard register. And routine recog is generated by back-end from target machine description file, which returns nonzero, if the RTL instruction is matched by patterns in the description file. At line 317, insn_data is also filled out by back-end, the predicate slot will select out valid operands for the RTL instruction. It is also settled by back-end. float_extend_from_mem records modes whether we can float-extend from memory.

 

dnSpy是目前业界广泛使用的一款.NET程序的反编译工具,支持32位和64位系统环境。它允许用户查看和编辑.NET汇编和反编译代码,以及调试.NET程序。该工具通常用于程序开发者在维护和调试过程中分析程序代码,尤其在源代码丢失或者无法获取的情况下,dnSpy能提供很大的帮助。 V6.1.8版本的dnSpy是在此系列软件更新迭代中的一个具体版本号,代表着该软件所具备的功能与性能已经达到了一个相对稳定的水平,对于处理.NET程序具有较高的可用性和稳定性。两个版本,即32位的dnSpy-net-win32和64位的dnSpy-net-win64,确保了不同操作系统架构的用户都能使用dnSpy进行软件分析。 32位的系统架构相较于64位,由于其地址空间的限制,只能支持最多4GB的内存空间使用,这在处理大型项目时可能会出现不足。而64位的系统能够支持更大的内存空间,使得在处理大型项目时更为方便。随着计算机硬件的发展,64位系统已经成为了主流,因此64位的dnSpy也更加受开发者欢迎。 压缩包文件名“dnSpy-net-win64.7z”和“dnSpy-net-win32.7z”中的“.7z”表示该压缩包采用了7-Zip压缩格式,它是一种开源的文件压缩软件,以其高压缩比著称。在实际使用dnSpy时,用户需要下载对应架构的压缩包进行解压安装,以确保软件能够正确运行在用户的操作系统上。 dnSpy工具V6.1.8版本的发布,对于.NET程序员而言,无论是32位系统还是64位系统用户,都是一个提升工作效率的好工具。用户可以根据自己计算机的操作系统架构,选择合适的版本进行下载使用。而对于希望进行深度分析.NET程序的开发者来说,这个工具更是不可或缺的利器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值