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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java实现敏感词过滤「建议收藏」

    java实现敏感词过滤「建议收藏」项目中的需要,对用户的输入进行敏感词的过滤,使用的是DFT算法,敏感词可以从数据库进行读取和配置.把代码整理了一下,可以直接使用完整工程下载地址:https://download.csdn.net/download/a897180673/10278921一共三个类,1个测试类,1个从数据库加载敏感词类,一个是实现DFT算法的类,具体的算法可以去研究.首先是从数据库加…

    2022年5月29日
    33
  • sensor DVP接口介绍

    sensor DVP接口介绍转载:https://blog.csdn.net/hua371242480/article/details/88629023原创sensor接口之DVP…

    2022年4月29日
    69
  • 2020最新-精选基础算法100题(面试必备)[通俗易懂]

    2020最新-精选基础算法100题(面试必备)[通俗易懂]0x01.概述作为一个程序员,算法能力必不可少,虽然不一定是算法工程师,但是算法还是彰显着个人的编码能力,面试中也经常会被问到,甚至会被要求临场做算法题,所以,还是好好积累吧。个人其实对算法挺有兴趣的,从3月份开始,陆陆续续刷了一些算法题,把一些有意义的记录下来了,也顺便写了一些题解,个人认为,还是挺有收获的。之前写了一篇算法文章的目录,不过后来就忘了实时去更新了,于是现在,想把之前做过的一些有意义的算法题分享出来,刚好整理了100篇比较有意义的。希望对大家有所帮助。0x02.说明关

    2022年6月7日
    53
  • XDOJ1145–组合数学四之Carnival Phantasm

    XDOJ1145–组合数学四之Carnival Phantasm描述:为解救可怜的武内崇老师,saber、远坂、爱尔奎特、希耶尔等人组成了第六科急救队!最终,由琥珀开发出了禁药,分身光线(这药是内服还是外用的==?),将爱尔奎特批量化生产,来对月世界进行全面的地毯式搜索。现已知,第六科共有m个复制人(每个复制人完全一样),月世界有n个城市,每个城市会被一个复制人搜索一遍。问:共有多少种分配方法。(根据时空管理局劳务法更定,每个复制人又要分得工作。)…

    2022年5月7日
    38
  • MySQL 字符集 注意事项

    MySQL 字符集 注意事项utf8 unicode ci 与 utf8 general ci 区别 utf8 unicode ci 和 utf8 general ci 对中英文来说没有实质的差别 utf8 general ci 校对速度快 但准确度稍差 utf8 unicode ci 准确度高 但校对速度稍慢 若数据库中有德语 法语或者俄语需求 需使用 utf8 unicode ci 其他情况用 utf8 general ci 即可 如果你想使用 gb2312 编码 那么建议你使用 latin1 作为数据表的默认字符集 这样就能直

    2025年12月12日
    5
  • phpmyadmin设置自动登录和取消自动登录

    phpmyadmin设置自动登录和取消自动登录

    2021年10月15日
    39

发表回复

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

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