@@ -40,6 +40,7 @@ local action_names = {
4040 " STOP" , " SECTION" , " ESC" , " REL_EXT" ,
4141 " ALIGN" , " REL_LG" , " LABEL_LG" ,
4242 " REL_PC" , " LABEL_PC" , " IMM" , " IMM6" , " IMM12" , " IMM13W" , " IMM13X" , " IMML" ,
43+ " VREG" ,
4344}
4445
4546-- Maximum number of section buffer positions for dasm_put().
@@ -246,9 +247,12 @@ local map_cond = {
246247
247248local parse_reg_type
248249
249- local function parse_reg (expr )
250+ local function parse_reg (expr , shift )
250251 if not expr then werror (" expected register name" ) end
251252 local tname , ovreg = match (expr , " ^([%w_]+):(@?%l%d+)$" )
253+ if not tname then
254+ tname , ovreg = match (expr , " ^([%w_]+):(R[xwqdshb]%b())$" )
255+ end
252256 local tp = map_type [tname or expr ]
253257 if tp then
254258 local reg = ovreg or tp .reg
@@ -266,18 +270,28 @@ local function parse_reg(expr)
266270 elseif parse_reg_type ~= rt then
267271 werror (" register size mismatch" )
268272 end
269- return r , tp
273+ return shl (r , shift ), tp
274+ end
275+ end
276+ local vrt , vreg = match (expr , " ^R([xwqdshb])(%b())$" )
277+ if vreg then
278+ if not parse_reg_type then
279+ parse_reg_type = vrt
280+ elseif parse_reg_type ~= vrt then
281+ werror (" register size mismatch" )
270282 end
283+ if shift then waction (" VREG" , shift , vreg ) end
284+ return 0
271285 end
272286 werror (" bad register name `" .. expr .. " '" )
273287end
274288
275289local function parse_reg_base (expr )
276290 if expr == " sp" then return 0x3e0 end
277- local base , tp = parse_reg (expr )
291+ local base , tp = parse_reg (expr , 5 )
278292 if parse_reg_type ~= " x" then werror (" bad register type" ) end
279293 parse_reg_type = false
280- return shl ( base , 5 ) , tp
294+ return base , tp
281295end
282296
283297local parse_ctx = {}
@@ -403,7 +417,7 @@ local function parse_imm_load(imm, scale)
403417 end
404418 werror (" out of range immediate `" .. imm .. " '" )
405419 else
406- waction (" IMML" , 0 , imm )
420+ waction (" IMML" , scale , imm )
407421 return 0
408422 end
409423end
462476
463477local function parse_load (params , nparams , n , op )
464478 if params [n + 2 ] then werror (" too many operands" ) end
479+ local scale = shr (op , 30 )
465480 local pn , p2 = params [n ], params [n + 1 ]
466481 local p1 , wb = match (pn , " ^%[%s*(.-)%s*%](!?)$" )
467482 if not p1 then
@@ -470,14 +485,13 @@ local function parse_load(params, nparams, n, op)
470485 if reg and tailr ~= " " then
471486 local base , tp = parse_reg_base (reg )
472487 if tp then
473- waction (" IMML" , 0 , format (tp .ctypefmt , tailr ))
488+ waction (" IMML" , scale , format (tp .ctypefmt , tailr ))
474489 return op + base
475490 end
476491 end
477492 end
478493 werror (" expected address operand" )
479494 end
480- local scale = shr (op , 30 )
481495 if p2 then
482496 if wb == " !" then werror (" bad use of '!'" ) end
483497 op = op + parse_reg_base (p1 ) + parse_imm (p2 , 9 , 12 , 0 , true ) + 0x400
@@ -494,7 +508,7 @@ local function parse_load(params, nparams, n, op)
494508 op = op + parse_imm_load (imm , scale )
495509 else
496510 local p2b , p3b , p3s = match (p2a , " ^,%s*([^,%s]*)%s*,?%s*(%S*)%s*(.*)$" )
497- op = op + shl ( parse_reg (p2b ) , 16 ) + 0x00200800
511+ op = op + parse_reg (p2b , 16 ) + 0x00200800
498512 if parse_reg_type ~= " x" and parse_reg_type ~= " w" then
499513 werror (" bad index register type" )
500514 end
@@ -620,7 +634,7 @@ local function alias_bfx(p)
620634end
621635
622636local function alias_bfiz (p )
623- parse_reg (p [1 ])
637+ parse_reg (p [1 ], 0 )
624638 if parse_reg_type == " w" then
625639 p [3 ] = " #-(" .. p [3 ]:sub (2 ).. " )%32"
626640 p [4 ] = " #(" .. p [4 ]:sub (2 ).. " )-1"
@@ -631,7 +645,7 @@ local function alias_bfiz(p)
631645end
632646
633647local alias_lslimm = op_alias (" ubfm_4" , function (p )
634- parse_reg (p [1 ])
648+ parse_reg (p [1 ], 0 )
635649 local sh = p [3 ]:sub (2 )
636650 if parse_reg_type == " w" then
637651 p [3 ] = " #-(" .. sh .. " )%32"
@@ -891,15 +905,15 @@ local function parse_template(params, template, nparams, pos)
891905 for p in gmatch (sub (template , 9 ), " ." ) do
892906 local q = params [n ]
893907 if p == " D" then
894- op = op + parse_reg (q ); n = n + 1
908+ op = op + parse_reg (q , 0 ); n = n + 1
895909 elseif p == " N" then
896- op = op + shl ( parse_reg (q ) , 5 ); n = n + 1
910+ op = op + parse_reg (q , 5 ); n = n + 1
897911 elseif p == " M" then
898- op = op + shl ( parse_reg (q ) , 16 ); n = n + 1
912+ op = op + parse_reg (q , 16 ); n = n + 1
899913 elseif p == " A" then
900- op = op + shl ( parse_reg (q ) , 10 ); n = n + 1
914+ op = op + parse_reg (q , 10 ); n = n + 1
901915 elseif p == " m" then
902- op = op + shl ( parse_reg (params [n - 1 ]) , 16 )
916+ op = op + parse_reg (params [n - 1 ], 16 )
903917
904918 elseif p == " p" then
905919 if q == " sp" then params [n ] = " @x31" end
0 commit comments