@@ -40,6 +40,7 @@ local action_names = {
40
40
" STOP" , " SECTION" , " ESC" , " REL_EXT" ,
41
41
" ALIGN" , " REL_LG" , " LABEL_LG" ,
42
42
" REL_PC" , " LABEL_PC" , " IMM" , " IMM6" , " IMM12" , " IMM13W" , " IMM13X" , " IMML" ,
43
+ " VREG" ,
43
44
}
44
45
45
46
-- Maximum number of section buffer positions for dasm_put().
@@ -246,9 +247,12 @@ local map_cond = {
246
247
247
248
local parse_reg_type
248
249
249
- local function parse_reg (expr )
250
+ local function parse_reg (expr , shift )
250
251
if not expr then werror (" expected register name" ) end
251
252
local tname , ovreg = match (expr , " ^([%w_]+):(@?%l%d+)$" )
253
+ if not tname then
254
+ tname , ovreg = match (expr , " ^([%w_]+):(R[xwqdshb]%b())$" )
255
+ end
252
256
local tp = map_type [tname or expr ]
253
257
if tp then
254
258
local reg = ovreg or tp .reg
@@ -266,18 +270,28 @@ local function parse_reg(expr)
266
270
elseif parse_reg_type ~= rt then
267
271
werror (" register size mismatch" )
268
272
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" )
270
282
end
283
+ if shift then waction (" VREG" , shift , vreg ) end
284
+ return 0
271
285
end
272
286
werror (" bad register name `" .. expr .. " '" )
273
287
end
274
288
275
289
local function parse_reg_base (expr )
276
290
if expr == " sp" then return 0x3e0 end
277
- local base , tp = parse_reg (expr )
291
+ local base , tp = parse_reg (expr , 5 )
278
292
if parse_reg_type ~= " x" then werror (" bad register type" ) end
279
293
parse_reg_type = false
280
- return shl ( base , 5 ) , tp
294
+ return base , tp
281
295
end
282
296
283
297
local parse_ctx = {}
@@ -403,7 +417,7 @@ local function parse_imm_load(imm, scale)
403
417
end
404
418
werror (" out of range immediate `" .. imm .. " '" )
405
419
else
406
- waction (" IMML" , 0 , imm )
420
+ waction (" IMML" , scale , imm )
407
421
return 0
408
422
end
409
423
end
462
476
463
477
local function parse_load (params , nparams , n , op )
464
478
if params [n + 2 ] then werror (" too many operands" ) end
479
+ local scale = shr (op , 30 )
465
480
local pn , p2 = params [n ], params [n + 1 ]
466
481
local p1 , wb = match (pn , " ^%[%s*(.-)%s*%](!?)$" )
467
482
if not p1 then
@@ -470,14 +485,13 @@ local function parse_load(params, nparams, n, op)
470
485
if reg and tailr ~= " " then
471
486
local base , tp = parse_reg_base (reg )
472
487
if tp then
473
- waction (" IMML" , 0 , format (tp .ctypefmt , tailr ))
488
+ waction (" IMML" , scale , format (tp .ctypefmt , tailr ))
474
489
return op + base
475
490
end
476
491
end
477
492
end
478
493
werror (" expected address operand" )
479
494
end
480
- local scale = shr (op , 30 )
481
495
if p2 then
482
496
if wb == " !" then werror (" bad use of '!'" ) end
483
497
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)
494
508
op = op + parse_imm_load (imm , scale )
495
509
else
496
510
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
498
512
if parse_reg_type ~= " x" and parse_reg_type ~= " w" then
499
513
werror (" bad index register type" )
500
514
end
@@ -620,7 +634,7 @@ local function alias_bfx(p)
620
634
end
621
635
622
636
local function alias_bfiz (p )
623
- parse_reg (p [1 ])
637
+ parse_reg (p [1 ], 0 )
624
638
if parse_reg_type == " w" then
625
639
p [3 ] = " #-(" .. p [3 ]:sub (2 ).. " )%32"
626
640
p [4 ] = " #(" .. p [4 ]:sub (2 ).. " )-1"
@@ -631,7 +645,7 @@ local function alias_bfiz(p)
631
645
end
632
646
633
647
local alias_lslimm = op_alias (" ubfm_4" , function (p )
634
- parse_reg (p [1 ])
648
+ parse_reg (p [1 ], 0 )
635
649
local sh = p [3 ]:sub (2 )
636
650
if parse_reg_type == " w" then
637
651
p [3 ] = " #-(" .. sh .. " )%32"
@@ -891,15 +905,15 @@ local function parse_template(params, template, nparams, pos)
891
905
for p in gmatch (sub (template , 9 ), " ." ) do
892
906
local q = params [n ]
893
907
if p == " D" then
894
- op = op + parse_reg (q ); n = n + 1
908
+ op = op + parse_reg (q , 0 ); n = n + 1
895
909
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
897
911
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
899
913
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
901
915
elseif p == " m" then
902
- op = op + shl ( parse_reg (params [n - 1 ]) , 16 )
916
+ op = op + parse_reg (params [n - 1 ], 16 )
903
917
904
918
elseif p == " p" then
905
919
if q == " sp" then params [n ] = " @x31" end
0 commit comments