LLVM Cpu0 新后端4

 想好好熟悉一下llvm开发一个新后端都要干什么,于是参考了老师的系列文章:

LLVM 后端实践笔记

代码在这里(还没来得及准备,先用网盘暂存一下):

链接: https://pan.baidu.com/s/1V_tZkt9uvxo5bnUufhMQ_Q?pwd=ggu5 提取码: ggu5 

之前的章节只介绍了汇编代码生成的内容,这一章,我们将介绍对 ELF 目标格式文件的支持以及如何使用 objdump 工具来验证生成的目标文件。这一章的功能上的较复杂的代码其实不是很多,主要是框架上的东西。(因此这一章节参考原作者的内容较多)

当 llc 指定 -filetype=obj 时,编译器会生成目标文件(而不是汇编文件),此时,AsmPrinter::OutStreamer 所引用的是 MCObjectStreamer(汇编时引用的是 MCAsmStreamer)。LLVM 官方认为这个结构是后端代码生成阶段非常好的一个设计。

关键的一个接口是Cpu0AsmPrinter::EmitInstruction(),这个接口调用 MCObjectStreamer::EmitInstruction() ,进而根据选择生成的目标文件格式(ELF,COFF等)调用对应的编码发射函数,如 ELF 使用 MCELFStreamer()::EmitInstToData()。此时会进入到 Cpu0MCCodeEmitter.cpp 文件的实现中,调用 Cpu0MCCodeEmitter::encodeInstruction(),配合 TableGen 生成的 Cpu0MCCodeEmitter::getBinaryCodeForInstr()等接口完成最后的发射。

获取待发射指令编码的调用过程为:

Cpu0MCCodeEmitter::encodeInstruction()中,调用TableGen生成的 Cpu0GenMCCodeEmitter.inc 中的 getBinaryCodeForInstr(),传入 MI.Opcode; getBinaryCodeForInstr() 将 MI.Operand 传入 Cpu0MCCodeEmitter::getMachineOpValue() 来获取操作数的编码,这还需要再配合 Cpu0GenRegisterInfo.inc 和 Cpu0GenInstrInfo.inc 中的编码信息;getBinaryCodeForInstr() 将操作数的编码和指令操作码统一返回给 encodeInstruction();

比如一个加法操作,%0 = add %1, %2 生成为 adds $v0, $at, $v1,除了 adds 指令的编码需要在 Cpu0GenInstrInfo.inc 中查看外,还需要通过getEncodingValue(Reg) 到 Cpu0GenRegisterInfo.inc 中查看寄存器的编码,寄存器的编码和编码位置都在 Cpu0RegisterInfo.td 文件中描述了。

目录

1. 新增的文件

1.1 MCTargetDesc/Cpu0AsmBackend.cpp/.h

1.2 MCTargetDesc/Cpu0ELFObjectWriter.cpp

1.3 MCTargetDesc/Cpu0ELFStreamer.cpp/.h

1.4 MCTargetDesc/Cpu0FixupKinds.h

1.5 MCTargetDesc/Cpu0MCCodeEmitter.cpp/.h

1.6 MCTargetDesc/Cpu0MCExpr.cpp/.h

1.7 MCTargetDesc/Cpu0TargetStreamer.cpp/.h

2. 修改的文件

2.1 MCTargetDesc/Cpu0MCTargetDesc.cpp/.h


1. 新增的文件

1.1 MCTargetDesc/Cpu0AsmBackend.cpp/.h

比较重要的一个文件,实现了 Cpu0AsmBackend 类,继承自 MCAsmBackend 类。这个类作为汇编器后端实现类,目前对 Fixup 信息的操作提供了接口,比如 applyFixup() 用来使能 Fixup 状态,getFixupKindInfo() 用来获取 Fixup 类型信息,getNumFixupKinds() 用来获取 Fixup 类型的数量,mayNeedRelaxation() 返回需要 relaxation 的指令的状态(目前是空),fixupNeedsRelaxation() 返回给定 fixup 下的指令是否需要 relaxation 的状态(目前是空)。

已经定义了一些常用的 fixup 类型,比如 32 位类型:fixup_Cpu0_32, fixup_Cpu0_HI16, fixup_Cpu0_LO16,还有 GOT 的一些 fixup 类型。这些函数都是对基类函数的覆写,有关于重定向的功能都将在之后的章节讲解,所以目前会留空。我们还在其中实现了两个工厂函数,createCpu0AsmBackendEL32() 和 createCpu0AsmBackendEB32(),用来返回一个 AsmBackend 的实例。

1.2 MCTargetDesc/Cpu0ELFObjectWriter.cpp

定义了一个叫 Cpu0ELFObjectWriter 的类,继承自 MCELFObjectTargetWriter 类。这个类将用来完成最终的 ELF 文件格式的写入任务。其中提供了 getRelocType() 方法用来获取重定位类型,needsRelocateWithSymbol() 判断某种重定位类型是否是符号重定位,默认大多数都是符号重定位。

1.3 MCTargetDesc/Cpu0ELFStreamer.cpp/.h

定义了一个叫 Cpu0ELFStreamer 的类,继承自 MCELFStreamer 类。另外定义了这个类的工厂函数 createCpu0ELFStreamer(),用来返回其对象。ELFStreamer 对象会注册到后端模块中。TargetStreamer 和 ELFStreamer 在生成 ELF 文件中同时起作用,ELFStreamer 是我们自定义的一个类,在其中可以做一些改动来调整输出内容。目前这些文件中都还是比较空的状态,我们先搭建整个框架。

1.4 MCTargetDesc/Cpu0FixupKinds.h

这个头文件中定义了 llvm::Cpu0::Fixups 的枚举值,这里的定义顺序必须与Cpu0AsmBackend.cpp 中的 MCFixupKindInfo 保持一致。

1.5 MCTargetDesc/Cpu0MCCodeEmitter.cpp/.h

另一个比较重要的类,用来为Streamer类提供直接发射编码的实现接口。定义了比如 encodeInstruction() 等重要接口。我们在 encodeInstruction() 中检查一些未完成编码设计的指令,这还需要考虑一些特殊情况,比如要排除编码为 0 的情况,排除伪指令(伪代码不应该出现在这这个阶段了)。getBinaryCodeForInstr() 函数是 TableGen 自动生成的,可以通过传入给定的 MI 指令,获取该指令的编码。

1.6 MCTargetDesc/Cpu0MCExpr.cpp/.h

针对操作数是表达式的情况,我们需要额外做处理。其中定义了Cpu0MCExpr类,继承自 MCTargetExpr类。其中声明了表达式类型 Cpu0ExprKind,还提供了 create(), getKind() 等接口。

1.7 MCTargetDesc/Cpu0TargetStreamer.cpp/.h

定义了一个叫 Cpu0TargetStreamer 的类,继承自 MCTargetStreamer 类。定义了一个叫 Cpu0TargetAsmStreamer 的类,继承自 Cpu0TargetStreamer 类,这个类用来完成汇编器 Streamer 的功能。AsmStreamer 对象会注册到后端模块中。

2. 修改的文件

2.1 MCTargetDesc/Cpu0MCTargetDesc.cpp/.h

我们知道这个文件中会完成注册一些后端模块的功能。首先定义了两个函数,createMCStreamer() 调用 createCpu0ELFStreamer() 用来建立 ELFStreamer 对象,createCpu0AsmTargetStreamer() 直接建立 Cpu0TargetAsmStreamer 对象。

然后就是调用TargetRegistry::RegisterELFStreamer()和 TargetRegistry::RegisterAsmTargetStreamer()来注册这两个对象模块。另外,还调用 TargetRegistry::RegisterMCCodeEmitter() 来注册大小端的 MCCodeEmitter 对象,以及调用 TargetRegistry::RegisterMCAsmBackend() 来注册大小端的 MCAsmBackend 对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/25033.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

向量数据库是什么?

向量数据库是什么? 随着人工智能和机器学习技术的迅猛发展,向量数据库作为一种新型数据库引起了广泛关注。向量数据库专门用于存储和查询高维向量数据,是在大规模数据检索和相似性搜索领域的重要工具。 向量数据库的定义 向量数据库是一种…

为下一波创新做准备:人工智能和元宇宙

人工智能和元宇宙的发展带来了独特的可能性和挑战。随着这些技术的发展,我们进入了一个沉浸式虚拟体验和智能系统的时代,我们正站在一个历史性的时刻。为迎接下一波创新,采取必要的措施是很重要的。 我们正在见证两项变革性技术的激动人心的发…

以sqlilabs靶场为例,讲解SQL注入攻击原理【54-65关】

【Less-54】 与前面的题目不同是,这里只能提交10次,一旦提交超过十次,数据会重新刷新,所有的步骤需要重来一次。 解题步骤: 根据测试,使用的是单引号闭合。 # 判断字段的数量 ?id1 order by 3 -- aaa# …

WPF视频学习-基础知识篇

1.简介WPF: C# 一套关于windows界面应用开发框架 2.WPF和winform的差别 ,(WPF比较新) 创建新项目使用模板: WPF使用.xaml后缀,双击可查看操作界面和设置代码,其文件展开之后中有MainWindow.xaml.cs为程序交互逻辑。…

【Python】数据处理:文本文件操作

在Python中,处理文本文件是非常常见的任务。可以使用内置的open函数来打开、读取和写入文本文件。 打开文件 使用open函数打开文件。该函数有两个主要参数: open(file, moder, buffering-1, encodingNone, errorsNone, newlineNone, closefdTrue, ope…

OmniGlue: Generalizable Feature Matching with Foundation Model Guidance

【引用格式】:Jiang H, Karpur A, Cao B, et al. OmniGlue: Generalizable Feature Matching with Foundation Model Guidance[J]. arXiv preprint arXiv:2405.12979, 2024. 【网址】:https://arxiv.org/pdf/2405.12979 【开源代码】:https…

Redis中的主从复制

分布式系统中的几种Redis部署方式 为了解决一个程序只部署在一个服务器上的单点问题: 可用性问题,如果这个机器挂了,就意味着服务就中断了 一个程序只部署在一台机器上,它的性能/支持的并发量也是有限的 所以,就引…

力扣 240.搜素矩阵II

题目描述: 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1: 输入:matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9…

openpose标定中棋盘格检测错误的解决方案

文章目录 1、openpose 棋盘格检测流程2、解决过程3、实测结果1、openpose 棋盘格检测流程 在opencv中通过调用cv::findChessboardCorners()函数,同时指定棋盘格内角点尺寸来检测画面中的棋盘格,结果将以一定顺序来保存结果。通常指定尺寸的两个纬度的值不能相同,例如当指定…

OpenCV 双目相机标定

文章目录 一、简介1.1单目相机标定1.2双目相机标定二、实现代码三、实现效果参考资料一、简介 1.1单目相机标定 与单目相机标定类似,双目标定的目的也是要找到从世界坐标转换为图像坐标所用到的投影P矩阵各个系数(即相机的内参与外参)。具体过程如下所述: 1、首先我们需要…

【STM32】ucOS-III多任务程序

【STM32】uc/OS-III多任务程序 文章目录 【STM32】uc/OS-III多任务程序STM32F103C8T6移植uC/OS-III基于HAL库超完整详细过程与相关实验实验任务实验过程一、 uC/OS-III源码下载二、 建立STM32CubeMX工程三、 复制uC/OS-III文件到工程文件夹四、 添加工程组件和头文件路径五、修…

数据结构之计数排序算法【图文详解】

P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。 P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。 博主主页:LiUEEEEE                        …

通过网址下载静态网页的仿站工具

下载地址:通过网址下载静态网页的仿站工具 超级实用的一款工具

学习笔记——路由网络基础——直连路由(direct)

二、直连路由(direct) 直连路由(direct):直接相连,接口配置好ip地址并up后自动生成的路由。默认优先级为0 Destination:表示路由的目的地址。用来标识IP包的目的地址或目的网络。 Mask:表示目的地址的子网掩码长度。 与目的地址…

MyBatisPlus总结二

MybatisPlus总结一在这: MybatisPlus总结1/2-CSDN博客 六、分页查询: 6.1.介绍: MybatisPlus内置了分页插件,所以我们只需要配置一个分页拦截器就可以了,由于不同的数据库的分页的方式不一样,例如mysql和…

轻松连接远程服务器SecureCRT for Mac/Windows

SecureCRT是一款功能强大的终端仿真器和文件传输工具,专为网络管理员、开发人员和系统工程师设计。它支持SSH、Telnet、RDP和串口等多种协议,提供安全、高效的远程访问和管理体验。SecureCRT具有多窗口/多标签管理、自定义终端仿真、颜色方案优化等高级功…

Linux内核下网卡硬件 MAC 和PHY分析笔记

1 简介 通常CPU自带的以太网接口是MAC控制器,为了实现完整的功能,外围硬件还需要增加一个PHY芯片。 PHY芯片在建立网络连接时负责协商确定网速、全双工 或者 半双工等。在正常通讯时负责在MAC控制器的MII信号 与 网线中的信号之间做转换。 本文的内核代…

最快的开源UDP传输工具:Kcptun

Kcptun:极速网络隧道,让数据传输飞起来!- 精选真开源,释放新价值。 概览 kcptun 是一个轻量级、高性能的TCP/UDP网络加速工具,由xtaci开发并托管在GitHub上。它通过使用kcp协议,为网络数据传输提供了一个快…

[linux] makefilegdb理解

目录 Linux项目自动化构建工具-make/Makefile 背景 理解 依赖关系 依赖方法 原理 Linux调试器-gdb使用 背景 开始使用 Linux项目自动化构建工具-make/Makefile 背景 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力 一个工…

推荐一款AI音乐生成工具和一款浏览器

大家好,今天给大家带来2款软件,一款是移动浏览器,一款是AI音乐生成软件。 Alook Alook是一款移动端浏览器,它以其独特的无广告、无推送、无新闻的"三无"特性,为用户提供了一个清爽的上网环境。Alook不仅界…