Skip to content

Commit a6535e5

Browse files
committed
squash merge develop branch into v2.4.5
1 parent dcf4ef9 commit a6535e5

14 files changed

Lines changed: 566 additions & 109 deletions

File tree

README.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,6 +1338,20 @@ Please see `LICENSE`_.
13381338
Changelog
13391339
=========
13401340

1341+
- `v2.4.5`_
1342+
1343+
* add x86/x64 internals 'mode' selector
1344+
* add 'lab' expression for labels
1345+
* improve MemoryZone/Map with a 'grep' method
1346+
* improve MemoryZone to allow "shifting" to some address
1347+
* improve x86 AT&T formatter
1348+
* add x64 decoder tests
1349+
* fix x64 rip-relative addressing mode
1350+
* fix many x64 specs
1351+
* add x64 packed-instructions semantics
1352+
* fix various x86 SSE instructions
1353+
* fix various x86 issues (fisttp/SETcc/PUSH imm8/movq)
1354+
13411355
- `v2.4.4`_
13421356

13431357
* add some SSE instruction semantics
@@ -1452,6 +1466,7 @@ Changelog
14521466
.. _ply: http://www.dabeaz.com/ply/
14531467
.. _zodb: http://www.zodb.org
14541468
.. _LICENSE: https://github.com/bdcht/amoco/blob/release/LICENSE
1469+
.. _v2.4.5: https://github.com/bdcht/amoco/releases/tag/v2.4.5
14551470
.. _v2.4.4: https://github.com/bdcht/amoco/releases/tag/v2.4.4
14561471
.. _v2.4.3: https://github.com/bdcht/amoco/releases/tag/v2.4.3
14571472
.. _v2.4.2: https://github.com/bdcht/amoco/releases/tag/v2.4.2

amoco/arch/x64/asm.py

Lines changed: 272 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ def i_RET(i,fmap):
9090
def i_HLT(i,fmap):
9191
fmap[rip] = top(64)
9292

93+
def i_XLATB(i,fmap):
94+
fmap[rip] = fmap[rip]+i.length
95+
_table = bx if i.misc['opdsz']==16 else ebx
96+
REX = i.misc['REX']
97+
W = 0
98+
if REX: W=REX[0]
99+
if W==1: _table = rbx
100+
fmap[al] = fmap(mem(_table+al.zeroextend(_table.size),8))
101+
93102
#------------------------------------------------------------------------------
94103
def _ins_(i,fmap,l):
95104
counter = cx if i.misc['adrsz'] else rcx
@@ -391,7 +400,7 @@ def i_JMPF(i,fmap):
391400
pc = fmap[rip]+i.length
392401

393402
#------------------------------------------------------------------------------
394-
def _loop_(i,fmap,cond):
403+
def _loop_(i,fmap,fcond):
395404
pc = fmap[rip]+i.length
396405
opdsz = 16 if i.misc['opdsz'] else 64
397406
src = i.operands[0].signextend(64)
@@ -402,20 +411,21 @@ def _loop_(i,fmap,cond):
402411
W = 0
403412
if REX: W=REX[0]
404413
if W==1: counter = rcx
414+
cond = fcond(zf,counter)
405415
fmap[counter] = fmap(counter)-1
406416
fmap[rip] = tst(fmap(cond), loc, pc)
407417

408418
def i_LOOP(i,fmap):
409-
cond = (counter!=0)
410-
_loop_(i,fmap,cond)
419+
fcond = lambda f,c: (c!=0)
420+
_loop_(i,fmap,fcond)
411421

412422
def i_LOOPE(i,fmap):
413-
cond = zf&(counter!=0)
414-
_loop_(i,fmap,cond)
423+
fcond = lambda f,c : f&(c!=0)
424+
_loop_(i,fmap,fcond)
415425

416426
def i_LOOPNE(i,fmap):
417-
cond = (~zf)&(counter!=0)
418-
_loop_(i,fmap,cond)
427+
fcond = lambda f,c : (~f)&(c!=0)
428+
_loop_(i,fmap,fcond)
419429

420430
#------------------------------------------------------------------------------
421431
def i_LSL(i,fmap):
@@ -1253,3 +1263,258 @@ def i_SYSRET(i,fmap):
12531263
fmap[rip] = top(64)
12541264
fmap[rsp] = top(64)
12551265

1266+
def i_PAND(i,fmap):
1267+
fmap[rip] = fmap[rip]+i.length
1268+
op1 = i.operands[0]
1269+
op2 = fmap(i.operands[1])
1270+
x=fmap(op1)&op2
1271+
fmap[op1] = x
1272+
1273+
def i_PANDN(i,fmap):
1274+
fmap[rip] = fmap[rip]+i.length
1275+
op1 = i.operands[0]
1276+
op2 = fmap(i.operands[1])
1277+
x=fmap(~op1)&op2
1278+
fmap[op1] = x
1279+
1280+
def i_POR(i,fmap):
1281+
fmap[rip] = fmap[rip]+i.length
1282+
op1 = i.operands[0]
1283+
op2 = fmap(i.operands[1])
1284+
x=fmap(op1)|op2
1285+
fmap[op1] = x
1286+
1287+
def i_PXOR(i,fmap):
1288+
fmap[rip] = fmap[rip]+i.length
1289+
op1 = i.operands[0]
1290+
op2 = fmap(i.operands[1])
1291+
x=fmap(op1)^op2
1292+
fmap[op1] = x
1293+
1294+
def i_MOVD(i,fmap):
1295+
fmap[rip] = fmap[rip]+i.length
1296+
op1 = i.operands[0]
1297+
op2 = fmap(i.operands[1])
1298+
fmap[op1] = op2[0:32].zeroextend(op1.size)
1299+
1300+
def i_MOVQ(i,fmap):
1301+
fmap[rip] = fmap[rip]+i.length
1302+
op1 = i.operands[0]
1303+
op2 = fmap(i.operands[1])
1304+
fmap[op1] = op2[0:64].zeroextend(op1.size)
1305+
1306+
def sse_MOVSD(i,fmap):
1307+
fmap[rip] = fmap[rip]+i.length
1308+
op1 = i.operands[0]
1309+
op2 = i.operands[1]
1310+
if op1._is_mem:
1311+
src = fmap(op2[0:op1.size])
1312+
elif op2._is_mem:
1313+
src = fmap(op2).zeroextend(op1.size)
1314+
fmap[op1] = src
1315+
1316+
def i_MOVDQU(i,fmap):
1317+
fmap[rip] = fmap[rip]+i.length
1318+
op1 = i.operands[0]
1319+
op2 = i.operands[1]
1320+
fmap[op1] = fmap(op2)
1321+
1322+
def i_MOVDQA(i,fmap):
1323+
fmap[rip] = fmap[rip]+i.length
1324+
op1 = i.operands[0]
1325+
op2 = i.operands[1]
1326+
fmap[op1] = fmap(op2)
1327+
1328+
def i_MOVUPS(i,fmap):
1329+
fmap[rip] = fmap[rip]+i.length
1330+
op1 = i.operands[0]
1331+
op2 = i.operands[1]
1332+
fmap[op1] = fmap(op2)
1333+
1334+
def i_MOVAPS(i,fmap):
1335+
fmap[rip] = fmap[rip]+i.length
1336+
op1 = i.operands[0]
1337+
op2 = i.operands[1]
1338+
fmap[op1] = fmap(op2)
1339+
1340+
def i_PADDB(i,fmap):
1341+
fmap[rip] = fmap[rip]+i.length
1342+
op1 = i.operands[0]
1343+
op2 = i.operands[1]
1344+
assert op1.size==op2.size
1345+
for __i in range(0,op1.size,8):
1346+
src1 = fmap(op1[__i:__i+8])
1347+
src2 = fmap(op2[__i:__i+8])
1348+
fmap[op1[__i:__i+8]] = src1+src2
1349+
1350+
def i_PSUBUSB(i,fmap):
1351+
fmap[rip] = fmap[rip]+i.length
1352+
op1 = i.operands[0]
1353+
op2 = i.operands[1]
1354+
assert op1.size==op2.size
1355+
for __i in range(0,op1.size,8):
1356+
src1 = fmap(op1[__i:__i+8])
1357+
src2 = fmap(op2[__i:__i+8])
1358+
res = src1-src2
1359+
fmap[op1[__i:__i+8]] = tst(src1<src2,cst(0,op1.size),res)
1360+
1361+
def i_PMAXUB(i,fmap):
1362+
fmap[rip] = fmap[rip]+i.length
1363+
op1 = i.operands[0]
1364+
op2 = i.operands[1]
1365+
assert op1.size==op2.size
1366+
for __i in range(0,op1.size,8):
1367+
src1 = fmap(op1[__i:__i+8])
1368+
src2 = fmap(op2[__i:__i+8])
1369+
fmap[op1[__i:__i+8]] = tst(src1>src2,src1,src2)
1370+
1371+
def i_PMINUB(i,fmap):
1372+
fmap[rip] = fmap[rip]+i.length
1373+
op1 = i.operands[0]
1374+
op2 = i.operands[1]
1375+
assert op1.size==op2.size
1376+
for __i in range(0,op1.size,8):
1377+
src1 = fmap(op1[__i:__i+8])
1378+
src2 = fmap(op2[__i:__i+8])
1379+
fmap[op1[__i:__i+8]] = tst(src1<src2,src1,src2)
1380+
1381+
def i_PUNPCKHBW(i,fmap):
1382+
fmap[rip] = fmap[rip]+i.length
1383+
op1 = i.operands[0]
1384+
op2 = i.operands[1]
1385+
assert op1.size==op2.size
1386+
src1 = fmap(op1)
1387+
src2 = fmap(op2)
1388+
val1 = (src1[i:i+8] for i in range(0,op1.size,8))
1389+
val2 = (src2[i:i+8] for i in range(0,op2.size,8))
1390+
res = [composer([v1,v2]) for (v1,v2) in zip(val1,val2)]
1391+
fmap[op1] = composer(res)[op1.size:2*op1.size]
1392+
1393+
def i_PUNPCKLBW(i,fmap):
1394+
fmap[rip] = fmap[rip]+i.length
1395+
op1 = i.operands[0]
1396+
op2 = i.operands[1]
1397+
assert op1.size==op2.size
1398+
src1 = fmap(op1)
1399+
src2 = fmap(op2)
1400+
val1 = (src1[i:i+8] for i in range(0,op1.size,8))
1401+
val2 = (src2[i:i+8] for i in range(0,op2.size,8))
1402+
res = [composer([v1,v2]) for (v1,v2) in zip(val1,val2)]
1403+
fmap[op1] = composer(res)[0:op1.size]
1404+
1405+
def i_PCMPEQB(i,fmap):
1406+
fmap[rip] = fmap[rip]+i.length
1407+
op1 = i.operands[0]
1408+
op2 = i.operands[1]
1409+
assert op1.size==op2.size
1410+
src1 = fmap(op1)
1411+
src2 = fmap(op2)
1412+
val1 = (src1[i:i+8] for i in range(0,op1.size,8))
1413+
val2 = (src2[i:i+8] for i in range(0,op2.size,8))
1414+
res = [tst(v1==v2,cst(0xff,8),cst(0,8)) for (v1,v2) in zip(val1,val2)]
1415+
fmap[op1] = composer(res)
1416+
1417+
def i_PSRLW(i,fmap):
1418+
fmap[rip] = fmap[rip]+i.length
1419+
op1 = i.operands[0]
1420+
op2 = i.operands[1]
1421+
src1 = fmap(op1)
1422+
src2 = fmap(op2)
1423+
val1 = (src1[i:i+16] for i in range(0,op1.size,16))
1424+
res = [v1>>src2.value for v1 in val1]
1425+
fmap[op1] = composer(res)
1426+
1427+
def i_PSRLD(i,fmap):
1428+
fmap[rip] = fmap[rip]+i.length
1429+
op1 = i.operands[0]
1430+
op2 = i.operands[1]
1431+
src1 = fmap(op1)
1432+
src2 = fmap(op2)
1433+
val1 = (src1[i:i+32] for i in range(0,op1.size,32))
1434+
res = [v1>>src2.value for v1 in val1]
1435+
fmap[op1] = composer(res)
1436+
1437+
def i_PSRLQ(i,fmap):
1438+
fmap[rip] = fmap[rip]+i.length
1439+
op1 = i.operands[0]
1440+
op2 = i.operands[1]
1441+
src1 = fmap(op1)
1442+
src2 = fmap(op2)
1443+
val1 = (src1[i:i+64] for i in range(0,op1.size,64))
1444+
res = [v1>>src2.value for v1 in val1]
1445+
fmap[op1] = composer(res)
1446+
1447+
def i_PSLLQ(i,fmap):
1448+
fmap[rip] = fmap[rip]+i.length
1449+
op1 = i.operands[0]
1450+
op2 = i.operands[1]
1451+
src1 = fmap(op1)
1452+
src2 = fmap(op2)
1453+
val1 = (src1[i:i+64] for i in range(0,op1.size,64))
1454+
res = [v1<<src2.value for v1 in val1]
1455+
fmap[op1] = composer(res)
1456+
1457+
def i_PSHUFD(i,fmap):
1458+
fmap[rip] = fmap[rip]+i.length
1459+
op1 = i.operands[0]
1460+
op2 = i.operands[1]
1461+
op3 = i.operands[2]
1462+
assert op1.size==op2.size==128
1463+
sz = 2
1464+
dst = []
1465+
src = fmap(op2)
1466+
order = fmap(op3)
1467+
j = 0
1468+
for i in range(0,op1.size,32):
1469+
dst.append( src[i:i+32]>>(order[j:j+sz]*32) )
1470+
j+=sz
1471+
fmap[op1] = composer(dst)
1472+
1473+
def i_PSHUFB(i,fmap):
1474+
fmap[rip] = fmap[rip]+i.length
1475+
op1 = i.operands[0]
1476+
op2 = i.operands[1]
1477+
assert op1.size==op2.size
1478+
sz = 4 if op1.size==128 else 3
1479+
src = fmap(op1)
1480+
mask = fmap(op2)
1481+
for i in range(0,op1.size,8):
1482+
srcb = src[i:i+8]
1483+
maskb = mask[i:i+8]
1484+
indx = maskb[0:sz]
1485+
if indx._is_cst:
1486+
sta,sto = indx.value*8,indx.value*8+8
1487+
v = src[sta:sto]
1488+
src[i:i+8] = tst(maskb[7:8],cst(0,8),v)
1489+
src[sta:sto] = tst(maskb[7:8],v,srcb)
1490+
else:
1491+
src[i:i+8] = tst(maskb[7:8],cst(0,8),top(8))
1492+
fmap[op1] = src
1493+
1494+
def i_PINSRW(i,fmap):
1495+
fmap[rip] = fmap[rip]+i.length
1496+
op1 = i.operands[0]
1497+
op2 = i.operands[1]
1498+
op3 = i.operands[2]
1499+
if op2._is_reg: op2 = op2[0:16]
1500+
src1 = fmap(op1)
1501+
src2 = fmap(op2)
1502+
if op3._is_cst:
1503+
sta,sto = op3.value*16,op3.value*16+16
1504+
src1[sta:sto] = src2
1505+
else:
1506+
src1 = top(src1.size)
1507+
fmap[op1] = src1
1508+
1509+
def i_PEXTRW(i,fmap):
1510+
fmap[rip] = fmap[rip]+i.length
1511+
op1 = i.operands[0]
1512+
op2 = i.operands[1]
1513+
op3 = i.operands[2]
1514+
src2 = fmap(op2)
1515+
if op3._is_cst:
1516+
sta,sto = op3.value*16,op3.value*16+16
1517+
v = src2[sta:sto]
1518+
else:
1519+
v = top(16)
1520+
fmap[op1] = v.zeroextend(op1.size)

amoco/arch/x64/env.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,5 @@ def dr(num):
108108

109109
xmmregs = [reg('xmm%d'%n, 128) for n in range(16)]
110110
ymmregs = [reg('ymm%d'%n, 256) for n in range(16)]
111+
112+
internals = {'mode':64}

amoco/arch/x64/formats.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def deref(op):
2424
base10 = True
2525
else:
2626
base10 = False
27-
s += '[%s%s]'%(op.a.base,op.a.disp_to_string(base10))
27+
s += '[%s%s]'%(op.a.base,op.a.disp_tostring(base10))
2828
return s
2929

3030
def opers(i):

0 commit comments

Comments
 (0)