luaJIT指令集介绍[通俗易懂]

luaJIT指令集介绍[通俗易懂]luaJIT指令集介绍—————-目录—————(a)相关ByteCode定义介绍(b)lj_bc.h和lj_bc.c(1)字节码format简介(2)操作数的相关范围定义,和部分定义常量(3)通过掩码镜像,来获取相对应区域的值(4)通过掩码镜像,来设置相对应区域的值(5)合成实现操作符(6)关于字节码指令的定义

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

luaJIT指令集介绍

—————-目录—————

(a)相关ByteCode定义介绍

(b)lj_bc.h和lj_bc.c

(1)字节码format简介

(2)操作数的相关范围定义,和部分定义常量

(3)通过掩码镜像,来获取相对应区域的值

(4)通过掩码镜像,来设置相对应区域的值

(5)合成实现操作符

(6)关于字节码指令的定义

(7)BCMode定义

(8)参数类型校验

————————————-

(a)相关ByteCode定义介绍

在luaJIT中定义了BCIns、BCReg、BCLine这4中类型,都是int32类型,也就是32位,关于为什么BC line number是有符号32位,这个在之后讨论

/* -- Common type definitions --------------------------------------------- */

/* Types for handling bytecodes. Need this here, details in lj_bc.h. */
typedef uint32_t BCIns;  //BC指令
typedef uint32_t BCPos;  //BC位置
typedef uint32_t BCReg;  //BC参数
typedef int32_t BCLine;  //BC行数

在之后的luaJIT字节码实现过程中,这4个类型是经常用到的

(b)lj_bc.h和lj_bc.c

(1)字节码format简介

/* Bytecode instruction format, 32 bit wide, fields of 8 or 16 bit:

** +—-+—-+—-+—-+
** | B  | C  | A  | OP | Format ABC
** +—-+—-+—-+—-+
** |    D    | A  | OP | Format AD
** +——————–

高位低位

这一部分描述了JIT,ByteCode的模板,相比于lua这里Bx变成了D,而Ax不存在了

(2)操作数的相关范围定义,和部分定义常量

	#define BCMAX_A		0xff A的最大范围	
	#define BCMAX_B		0xff B的最大范围
	#define BCMAX_C		0xff C的最大范围
	#define BCMAX_D		0xffff D的最大范围
	#define BCBIAS_J	0x8000 跳转指令标记码
	#define NO_REG		BCMAX_A 没有参数定义
	#define NO_JMP		(~(BCPos)0) 没有跳转定义

这一部分定义了操作参数的范围,还有几个常量定义

(3)通过掩码镜像,来获取相对应区域的值

 /* Macros to get instruction fields. */
 #define bc_op(i)	((BCOp)((i)&0xff))
 #define bc_a(i)		((BCReg)(((i)>>8)&0xff))
 #define bc_b(i)		((BCReg)((i)>>24))
 #define bc_c(i)		((BCReg)(((i)>>16)&0xff))
 #define bc_d(i)		((BCReg)((i)>>16))
 #define bc_j(i)		((ptrdiff_t)bc_d(i)-BCBIAS_J)

这一部分定义了如何获取相对应的参数的值,从这里也可以看出,各个参数区域的位置

(4)通过掩码镜像,来设置相对应区域的值

 #define setbc_byte(p, x, ofs) \
   ((uint8_t *)(p))[LJ_ENDIAN_SELECT(ofs, 3-ofs)] = (uint8_t)(x) 这就是一种贼骚的操作,先把32位转换成8位指针,强行分成4组后做处理
 #define setbc_op(p, x)	setbc_byte(p, (x), 0) 
 #define setbc_a(p, x)	setbc_byte(p, (x), 1)
 #define setbc_b(p, x)	setbc_byte(p, (x), 3)
 #define setbc_c(p, x)	setbc_byte(p, (x), 2)
 #define setbc_d(p, x) \
   ((uint16_t *)(p))[LJ_ENDIAN_SELECT(1, 0)] = (uint16_t)(x) 这里一样,强行拆成两组然后做骚操作
 #define setbc_j(p, x)	setbc_d(p, (BCPos)((int32_t)(x)+BCBIAS_J)) 设置跳转,用BCBIAS_J做标记


(5)合成实现操作符

 /* Macros to compose instructions. */
 #define BCINS_ABC(o, a, b, c) \
   (((BCIns)(o))|((BCIns)(a)<<8)|((BCIns)(b)<<24)|((BCIns)(c)<<16)) 这一部分实现合成操作码指令
 #define BCINS_AD(o, a, d) \
   (((BCIns)(o))|((BCIns)(a)<<8)|((BCIns)(d)<<16))
 #define BCINS_AJ(o, a, j)	BCINS_AD(o, a, (BCPos)((int32_t)(j)+BCBIAS_J)) 这一部分合成跳转指令


(6)关于字节码指令的定义

tips:

 EQ 就是 EQUAL等于
 NQ 就是 NOT EQUAL不等于
 GT 就是 GREATER THAN大于 
 LT 就是 LESS THAN小于
 GE 就是 GREATER THAN OR EQUAL 大于等于
 LE 就是 LESS THAN OR EQUAL 小于等于


	/* Bytecode instruction definition. Order matters, see below.
	**
	** (name, filler, Amode, Bmode, Cmode or Dmode, metamethod)还有相对应的元操作
	**
	** The opcode name suffixes specify the type for RB/RC or RD:
	** V = variable slot局部变量表
	** S = string const
	** N = number const
	** P = primitive type (~itype) 私有变量
	** B = unsigned byte literal 原义字符
	** M = multiple args/results 多参数和返回
	

后缀命名指定 说明不同的后缀存有不同的意义*/
	#define BCDEF(_) \
  	/* Comparison ops. ORDER OPR. */ \
  	_(ISLT,		var,	___,	var,	lt) \
  	_(ISGE,		var,	___,	var,	lt) \
  	_(ISLE,		var,	___,	var,	le) \
  	_(ISGT,		var,	___,	var,	le) \
 	 \
 	_(ISEQV,	var,	___,	var,	eq) \
  	_(ISNEV,	var,	___,	var,	eq) \
  	_(ISEQS,	var,	___,	str,	eq) \
  	_(ISNES,	var,	___,	str,	eq) \
  	_(ISEQN,	var,	___,	num,	eq) \
  	_(ISNEN,	var,	___,	num,	eq) \
  	_(ISEQP,	var,	___,	pri,	eq) \
  	_(ISNEP,	var,	___,	pri,	eq) \
  	\
  	/* Unary test and copy ops. */ \
  	_(ISTC,		dst,	___,	var,	___) \
  	_(ISFC,		dst,	___,	var,	___) \
  	_(IST,		___,	___,	var,	___) \
  	_(ISF,		___,	___,	var,	___) \
  	\
  	/* Unary ops. */ \
  	_(MOV,		dst,	___,	var,	___) \
  	_(NOT,		dst,	___,	var,	___) \
  	_(UNM,		dst,	___,	var,	unm) \
  	_(LEN,		dst,	___,	var,	len) \
  	\
  	/* Binary ops. ORDER OPR. VV last, POW must be next. */ \
  	_(ADDVN,	dst,	var,	num,	add) \
  	_(SUBVN,	dst,	var,	num,	sub) \
  	_(MULVN,	dst,	var,	num,	mul) \
  	_(DIVVN,	dst,	var,	num,	div) \
  	_(MODVN,	dst,	var,	num,	mod) \
  	\
  	_(ADDNV,	dst,	var,	num,	add) \
  	_(SUBNV,	dst,	var,	num,	sub) \
  	_(MULNV,	dst,	var,	num,	mul) \
  	_(DIVNV,	dst,	var,	num,	div) \
  	_(MODNV,	dst,	var,	num,	mod) \
  	\
  	_(ADDVV,	dst,	var,	var,	add) \
  	_(SUBVV,	dst,	var,	var,	sub) \
  	_(MULVV,	dst,	var,	var,	mul) \
  	_(DIVVV,	dst,	var,	var,	div) \
  	_(MODVV,	dst,	var,	var,	mod) \
  	\
  	_(POW,		dst,	var,	var,	pow) \
  	_(CAT,		dst,	rbase,	rbase,	concat) \
  	\
  	/* Constant ops. */ \
  	_(KSTR,		dst,	___,	str,	___) \
  	_(KCDATA,	dst,	___,	cdata,	___) \
  	_(KSHORT,	dst,	___,	lits,	___) \
  	_(KNUM,		dst,	___,	num,	___) \
  	_(KPRI,		dst,	___,	pri,	___) \
  	_(KNIL,		base,	___,	base,	___) \
  	\
  	/* Upvalue and function ops. */ \
  	_(UGET,		dst,	___,	uv,	___) \
  	_(USETV,	uv,	___,	var,	___) \
  	_(USETS,	uv,	___,	str,	___) \
  	_(USETN,	uv,	___,	num,	___) \
  	_(USETP,	uv,	___,	pri,	___) \
  	_(UCLO,		rbase,	___,	jump,	___) \
  	_(FNEW,		dst,	___,	func,	gc) \
  	\
  	/* Table ops. */ \
  	_(TNEW,	dst,	___,	lit,	gc) \
  	_(TDUP,	dst,	___,	tab,	gc) \
  	_(GGET,	dst,	___,	str,	index) \
  	_(GSET,	var,	___,	str,	newindex) \
  	_(TGETV,	dst,	var,	var,	index) \
  	_(TGETS,	dst,	var,	str,	index) \
  	_(TGETB,	dst,	var,	lit,	index) \
  	_(TSETV,	var,	var,	var,	newindex) \
  	_(TSETS,	var,	var,	str,	newindex) \
  	_(TSETB,	var,	var,	lit,	newindex) \
  	_(TSETM,	base,	___,	num,	newindex) \
  	\
  	/* Calls and vararg handling. T = tail call. */ \
  	_(CALLM,	base,	lit,	lit,	call) \
  	_(CALL,	base,	lit,	lit,	call) \
  	_(CALLMT,	base,	___,	lit,	call) \
  	_(CALLT,	base,	___,	lit,	call) \
  	_(ITERC,	base,	lit,	lit,	call) \
  	_(ITERN,	base,	lit,	lit,	call) \
  	_(VARG,	base,	lit,	lit,	___) \
  	_(ISNEXT,	base,	___,	jump,	___) \
  	\
  	/* Returns. */ \
  	_(RETM,		base,	___,	lit,	___) \
  	_(RET,		rbase,	___,	lit,	___) \
  	_(RET0,		rbase,	___,	lit,	___) \
  	_(RET1,		rbase,	___,	lit,	___) \
  	\
  	/* Loops and branches. I/J = interp/JIT, I/C/L = init/call/loop. */ \
  	_(FORI,		base,	___,	jump,	___) \
  	_(JFORI,	base,	___,	jump,	___) \
  	\
  	_(FORL,		base,	___,	jump,	___) \
  	_(IFORL,	base,	___,	jump,	___) \
  	_(JFORL,	base,	___,	lit,	___) \
  	\
  	_(ITERL,	base,	___,	jump,	___) \
  	_(IITERL,	base,	___,	jump,	___) \
  	_(JITERL,	base,	___,	lit,	___) \
  	\
  	_(LOOP,		rbase,	___,	jump,	___) \
  	_(ILOOP,	rbase,	___,	jump,	___) \
  	_(JLOOP,	rbase,	___,	lit,	___) \
  	\
  	_(JMP,		rbase,	___,	jump,	___) \
  	\
  	/* Function headers. I/J = interp/JIT, F/V/C = fixarg/vararg/C func. */ \
  	_(FUNCF,	rbase,	___,	___,	___) \
  	_(IFUNCF,	rbase,	___,	___,	___) \
  	_(JFUNCF,	rbase,	___,	lit,	___) \
  	_(FUNCV,	rbase,	___,	___,	___) \
  	_(IFUNCV,	rbase,	___,	___,	___) \
  	_(JFUNCV,	rbase,	___,	lit,	___) \
  	_(FUNCC,	rbase,	___,	___,	___) \
  	_(FUNCCW,	rbase,	___,	___,	___)

在这之后以下两行代码处理了这部分的定义

/* Bytecode opcode numbers. */

typedef enum {

#define BCENUM(name, ma, mb, mc, mt) BC_##name,

BCDEF(BCENUM)

#undef BCENUM

  BC__MAX

} BCOp;

这里对之前定义过得BENUM完全undef了,这也就表明这里的枚举,仅仅是枚举用,命名为BC_操作名

/* This solves a circular dependency problem, change as needed. */

#define FF_next_N 4

这里说FF_next_N是用来解决循环依赖问题的,之后可以关注下

(7)BCMode定义

typedef enum {

  BCMnone, BCMdst, BCMbase, BCMvar, BCMrbase, BCMuv,  /* Mode A must be <= 7 */

  BCMlit, BCMlits, BCMpri, BCMnum, BCMstr, BCMtab, BCMfunc, BCMjump, BCMcdata,

  BCM_max

} BCMode;

这里定义了BCMode的类型,这里主要是定义参数类型,因为扩展了很多操作指令,所以参数类型的也变得更丰富

(8)参数类型校验

这里的参数校验定义为

a 0~2 位

b 3~6位

c 7~10位

d 与c相同,但是有hasd这个校验步骤,就是检验b是不是modeNone

mm 11位以后

到这里全部的指令集定义已经完全介绍完毕,接下来将介绍read和write来进一步讲解






版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/185028.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ubuntu14.04 安装pycharm

    ubuntu14.04 安装pycharm参考链接:http://itsfoss.com/install-pycharm-ubuntu/怎样在ubuntu14.04上安装pycharmpycharm是一款为python开发而生的IDE。它已经被专家认为是最好的pythonIDE之一。pycharm有社区版和专业版两种。社区版是免费的。但是专业版有更多的功能。我在下面的教程中展示如何安装这两种pycharm。…

    2022年8月25日
    8
  • 无法解析的外部符号问题小结

    无法解析的外部符号问题小结问题1:在编写通信相关程序中,引用了一个静态库(该静态库编译没有问题,并被其他项目引用),该库是对SOCKET的一个封装。基本结构如下: 在属性中添加了该库的引用后,编译仍然报错,错误如下:safmq2005.lib(tcpsocket.obj):errorLNK2019:无法解析的外部符号_gethostbyname@4,该符号在函数”publ

    2022年6月28日
    59
  • Mit6.S081学习记录

    Mit6.S081学习记录这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML图表FLowchart流程图导出与导入导出导入欢迎使用Markdown编辑器你好!这是你第一次使用Markdown编辑器所展示的欢迎页。如果你想学习如何使用Mar

    2022年6月6日
    27
  • matlab流场可视化后处理「建议收藏」

    matlab流场可视化后处理「建议收藏」matlab流场可视化后处理1流体中标量的可视化1.1云图1.2切片图绘制1.3三维等值面图绘制2流体中矢量的可视化2.1箭头图或速度图2.2流线图2.4带节点的流线图2.5流管图和流带图2.6圆锥体图2.7粒子动画图3参考链接1流体中标量的可视化流体力学中常见的标量为位置、速度绝对值、压强等。1.1云图常用的云图绘制有pcolor、image、imagesc、imsh…

    2025年6月16日
    3
  • python的多线程是否没有用了[通俗易懂]

    python的多线程是否没有用了[通俗易懂]python的多线程是否就完全没有用了呢?相同的代码,为何有时候多线程会比单线程慢,有时又会比单线程快? 这主要跟运行的代码有关: 1、 CPU密集型代码 (

    2022年7月3日
    38
  • 14个简单有用的android源码,适合初学者

    1:查看是否有存储卡插入String status=Environment.getExternalStorageState();if(status.equals(Enviroment.MEDIA_MOUNTED)){ ;//说明有SD卡插入}2:让某个Activity透明在OnCreate 中不设Layout,然后this.setTheme(R.style.Th

    2022年3月9日
    43

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号