# Memory

The Hexagon processor features a load/store architecture, where
numeric and logical instructions operate on registers. Explicit load
instructions move operands from memory to registers, while store
instructions move operands from registers to memory. A few
instructions (mem-ops) perform numeric and logical operations
directly on memory.

The address space is unified: all accesses target the same linear
address space, which contains both instructions and data.

## Hexagon processor memory model

### Address space

The Hexagon processor has a 32-bit byte-addressable memory address
space. The user application may access the entire linear address space.
The Hexagon processor provides a virtual-to-physical address translation mechanism.

### Byte order

The Hexagon processor is a little endian machine: the lowest address
byte in memory is held in the least significant byte of a register,
as shown in [Hexagon processor byte order](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-fig-hexagon-processor-byte-order).

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by Microsoft Visio, SVG Export fig_hexagon_byte_order.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="5.07812in" height="2.74437in" viewbox="0 0 365.625 197.595" xml:space="preserve" color-interpolation-filters="sRGB" class="st5"><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvConvertTheme"></v:ud>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-1 .st1 { fill: none; stroke: #2a2aea; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.24 }
.svg-1 .st2 { fill: #2a2aea; font-family: Roboto; font-size: 0.75em }
.svg-1 .st3 { fill: none; stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.72 }
.svg-1 .st4 { font-size: 1em }
.svg-1 .st5 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<g v:mid="0" v:index="1" v:groupcontext="foregroundPage">	<v:userdefs>		<v:ud v:nameu="SchemeName" v:val="VT4(Default)"></v:ud>	</v:userdefs>	<title>Page-1</title>	<v:pageproperties v:drawingscale="1" v:pagescale="1" v:drawingunits="0" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<v:layer v:name="Connector" v:index="0"></v:layer>	<g id="shape1-1" v:mid="1" v:groupcontext="shape" transform="translate(79.11,-144.36)">		<title>Rectangle.224</title>		<desc>A</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.06" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>A</text>		</g>	<g id="shape2-4" v:mid="2" v:groupcontext="shape" transform="translate(259.11,-120.735)">		<title>Sheet.2</title>		<desc>0</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="8.34375" cy="193.095" width="16.69" height="9"></v:textrect>		<rect x="0" y="188.595" width="16.6875" height="9" class="st3"></rect>		<text x="5.82" y="195.8" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>0</text>		</g>	<g id="shape3-7" v:mid="3" v:groupcontext="shape" transform="translate(188.422,-122.985)">		<title>Sheet.3</title>		<desc>31</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="11.0212" cy="193.095" width="22.05" height="9"></v:textrect>		<rect x="0" y="188.595" width="22.0425" height="9" class="st3"></rect>		<text x="5.97" y="195.8" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>31</text>		</g>	<g id="shape4-10" v:mid="4" v:groupcontext="shape" transform="translate(18.36,-163.485)">		<title>Sheet.4</title>		<desc>Address Contents</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="51.75" cy="189.72" width="103.5" height="15.75"></v:textrect>		<rect x="0" y="181.845" width="103.5" height="15.75" class="st3"></rect>		<text x="12.63" y="192.42" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Address    Contents</text>		</g>	<g id="shape5-13" v:mid="5" v:groupcontext="shape" transform="translate(79.11,-126.36)">		<title>Rectangle.17</title>		<desc>B</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.2" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>B</text>		</g>	<g id="shape6-16" v:mid="6" v:groupcontext="shape" transform="translate(79.11,-108.36)">		<title>Rectangle.18</title>		<desc>C</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.07" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>C</text>		</g>	<g id="shape7-19" v:mid="7" v:groupcontext="shape" transform="translate(79.11,-90.36)">		<title>Rectangle.19</title>		<desc>D</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.05" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>D</text>		</g>	<g id="shape8-22" v:mid="8" v:groupcontext="shape" transform="translate(79.11,-72.36)">		<title>Rectangle.20</title>		<desc>E</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.44" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>E</text>		</g>	<g id="shape9-25" v:mid="9" v:groupcontext="shape" transform="translate(79.11,-54.36)">		<title>Rectangle.9</title>		<desc>F</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.51" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>F</text>		</g>	<g id="shape10-28" v:mid="10" v:groupcontext="shape" transform="translate(79.11,-36.36)">		<title>Rectangle.10</title>		<desc>G</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="5.93" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>G</text>		</g>	<g id="shape11-31" v:mid="11" v:groupcontext="shape" transform="translate(79.11,-18.36)">		<title>Rectangle.11</title>		<desc>H</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="5.79" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>H</text>		</g>	<g id="shape12-34" v:mid="12" v:groupcontext="shape" transform="translate(43.11,-144.36)">		<title>Sheet.12</title>		<desc>0</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st3"></rect>		<text x="6.47" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>0</text>		</g>	<g id="shape13-37" v:mid="13" v:groupcontext="shape" transform="translate(43.11,-126.36)">		<title>Sheet.13</title>		<desc>1</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st3"></rect>		<text x="6.47" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>1</text>		</g>	<g id="shape14-40" v:mid="14" v:groupcontext="shape" transform="translate(43.11,-108.36)">		<title>Sheet.14</title>		<desc>2</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st3"></rect>		<text x="6.47" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>2</text>		</g>	<g id="shape15-43" v:mid="15" v:groupcontext="shape" transform="translate(43.11,-90.36)">		<title>Sheet.15</title>		<desc>3</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st3"></rect>		<text x="6.47" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>3</text>		</g>	<g id="shape16-46" v:mid="16" v:groupcontext="shape" transform="translate(43.11,-72.36)">		<title>Sheet.16</title>		<desc>4</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st3"></rect>		<text x="6.47" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>4</text>		</g>	<g id="shape17-49" v:mid="17" v:groupcontext="shape" transform="translate(43.11,-54.36)">		<title>Sheet.17</title>		<desc>5</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st3"></rect>		<text x="6.47" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>5</text>		</g>	<g id="shape18-52" v:mid="18" v:groupcontext="shape" transform="translate(43.11,-36.36)">		<title>Sheet.18</title>		<desc>6</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st3"></rect>		<text x="6.47" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>6</text>		</g>	<g id="shape19-55" v:mid="19" v:groupcontext="shape" transform="translate(43.11,-18.36)">		<title>Sheet.19</title>		<desc>7</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st3"></rect>		<text x="6.47" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>7</text>		</g>	<g id="shape20-58" v:mid="20" v:groupcontext="shape" transform="translate(268.11,-104.985)">		<title>Sheet.20</title>		<desc>Load byte</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="25.1775" cy="189.72" width="50.36" height="15.75"></v:textrect>		<rect x="0" y="181.845" width="50.355" height="15.75" class="st3"></rect>		<text x="5.58" y="192.42" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Load byte</text>		</g>	<g id="shape21-61" v:mid="21" v:groupcontext="shape" transform="translate(250.11,-102.735)">		<title>Rectangle.21</title>		<desc>A</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.06" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>A</text>		</g>	<g id="shape22-64" v:mid="22" v:groupcontext="shape" transform="translate(232.11,-102.735)">		<title>Rectangle.22</title>		<desc>-</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="7.76" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>-</text>		</g>	<g id="shape23-67" v:mid="23" v:groupcontext="shape" transform="translate(214.11,-102.735)">		<title>Rectangle.41</title>		<desc>-</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="7.76" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>-</text>		</g>	<g id="shape24-70" v:mid="24" v:groupcontext="shape" transform="translate(196.11,-102.735)">		<title>Rectangle.42</title>		<desc>-</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="7.76" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>-</text>		</g>	<g id="shape25-73" v:mid="25" v:groupcontext="shape" transform="translate(250.11,-75.735)">		<title>Rectangle.25</title>		<desc>A</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.06" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>A</text>		</g>	<g id="shape26-76" v:mid="26" v:groupcontext="shape" transform="translate(232.11,-75.735)">		<title>Rectangle.26</title>		<desc>B</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.2" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>B</text>		</g>	<g id="shape27-79" v:mid="27" v:groupcontext="shape" transform="translate(214.11,-75.735)">		<title>Rectangle.27</title>		<desc>-</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="7.76" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>-</text>		</g>	<g id="shape28-82" v:mid="28" v:groupcontext="shape" transform="translate(196.11,-75.735)">		<title>Rectangle.28</title>		<desc>-</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="7.76" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>-</text>		</g>	<g id="shape29-85" v:mid="29" v:groupcontext="shape" transform="translate(250.11,-48.735)">		<title>Rectangle.29</title>		<desc>A</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.06" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>A</text>		</g>	<g id="shape30-88" v:mid="30" v:groupcontext="shape" transform="translate(232.11,-48.735)">		<title>Rectangle.30</title>		<desc>B</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.2" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>B</text>		</g>	<g id="shape31-91" v:mid="31" v:groupcontext="shape" transform="translate(214.11,-48.735)">		<title>Rectangle.43</title>		<desc>C</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.07" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>C</text>		</g>	<g id="shape32-94" v:mid="32" v:groupcontext="shape" transform="translate(196.11,-48.735)">		<title>Rectangle.44</title>		<desc>D</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.05" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>D</text>		</g>	<g id="shape33-97" v:mid="33" v:groupcontext="shape" transform="translate(250.11,-21.735)">		<title>Rectangle.45</title>		<desc>A</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.06" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>A</text>		</g>	<g id="shape34-100" v:mid="34" v:groupcontext="shape" transform="translate(232.11,-21.735)">		<title>Rectangle.46</title>		<desc>B</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.2" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>B</text>		</g>	<g id="shape35-103" v:mid="35" v:groupcontext="shape" transform="translate(214.11,-21.735)">		<title>Rectangle.47</title>		<desc>C</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.07" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>C</text>		</g>	<g id="shape36-106" v:mid="36" v:groupcontext="shape" transform="translate(196.11,-21.735)">		<title>Rectangle.48</title>		<desc>D</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.05" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>D</text>		</g>	<g id="shape37-109" v:mid="37" v:groupcontext="shape" transform="translate(178.11,-21.735)">		<title>Rectangle.49</title>		<desc>E</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.44" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>E</text>		</g>	<g id="shape38-112" v:mid="38" v:groupcontext="shape" transform="translate(160.11,-21.735)">		<title>Rectangle.50</title>		<desc>F</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="6.51" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>F</text>		</g>	<g id="shape39-115" v:mid="39" v:groupcontext="shape" transform="translate(142.11,-21.735)">		<title>Rectangle.51</title>		<desc>G</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="5.93" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>G</text>		</g>	<g id="shape40-118" v:mid="40" v:groupcontext="shape" transform="translate(124.11,-21.735)">		<title>Rectangle.52</title>		<desc>H</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="9" cy="188.595" width="18" height="18"></v:textrect>		<rect x="0" y="179.595" width="18" height="18" class="st1"></rect>		<text x="5.79" y="191.3" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>H</text>		</g>	<g id="shape41-121" v:mid="41" v:groupcontext="shape" transform="translate(268.065,-76.86)">		<title>Sheet.41</title>		<desc>Load halfword</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="32.4" cy="189.72" width="64.8" height="15.75"></v:textrect>		<rect x="0" y="181.845" width="64.8" height="15.75" class="st3"></rect>		<text x="22.43" y="187.02" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Load <tspan x="14.81" dy="1.2em" class="st4">halfword</tspan></text>		</g>	<g id="shape42-125" v:mid="42" v:groupcontext="shape" transform="translate(268.11,-48.735)">		<title>Sheet.42</title>		<desc>Load word</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="25.1775" cy="189.72" width="50.36" height="15.75"></v:textrect>		<rect x="0" y="181.845" width="50.355" height="15.75" class="st3"></rect>		<text x="4.08" y="192.42" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Load word</text>		</g>	<g id="shape43-128" v:mid="43" v:groupcontext="shape" transform="translate(268.065,-22.86)">		<title>Sheet.43</title>		<desc>Load doubleword</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="39.6" cy="189.72" width="79.2" height="15.75"></v:textrect>		<rect x="0" y="181.845" width="79.2" height="15.75" class="st3"></rect>		<text x="4.92" y="192.42" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Load doubleword</text>		</g>	<g id="shape44-131" v:mid="44" v:groupcontext="shape" transform="translate(124.065,-39.735)">		<title>Sheet.44</title>		<desc>63</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="10.8" cy="193.095" width="21.6" height="9"></v:textrect>		<rect x="0" y="188.595" width="21.6" height="9" class="st3"></rect>		<text x="5.75" y="195.8" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>63</text>		</g>	<g id="shape45-134" v:mid="45" v:groupcontext="shape" transform="translate(137.61,-143.235)">		<title>Sheet.45</title>		<desc>Register contents</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="51.75" cy="189.72" width="103.5" height="15.75"></v:textrect>		<rect x="0" y="181.845" width="103.5" height="15.75" class="st3"></rect>		<text x="16.64" y="192.42" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Register contents</text>		</g></g>
</svg>

**Hexagon processor byte order**

### Alignment

Even though the Hexagon processor memory is byte-addressable,
instructions and data must be aligned in memory on specific address
boundaries:

- Instructions and instruction packets must be 32-bit aligned
- Data must be aligned to its native access size.

Any unaligned memory access causes a memory-alignment exception.

Use the [permute](https://docs.qualcomm.com/doc/80-N2040-60/topic/data-processing.html#v79-prm-permute) instructions in applications that must
reference unaligned vector data. The loads and stores still must be
memory-aligned; however, the permute instructions enable
rearrangement of the data in registers.

Memory alignment restrictions

| **Data type** | **Size (bits)** | **Exception when** |
| --- | --- | --- |
| Byte Unsigned byte | 8 | Never |
| Halfword Unsigned halfword | 16 | LSB[0] != 0 [\[1\]](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#mem1) |
| Word Unsigned word | 32 | LSB[1:0] != 00 |
| Doubleword | 64 | LSB[2:0] != 000 |
| Instruction Instruction packet | 32 | LSB[1:0] != 00 |

[[1](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#id1)]

LSB = Least significant bits of address

## Memory loads

The Hexagon processor loads data from memory in byte, halfword, word, or doubleword sizes.
The data types supported are signed or unsigned. The syntax used is
memXX, where XX denotes the data type. The memory load instructions belong to the LD
instruction class and can only execute in slots 0 or 1.

Load instructions

| **Syntax** | **Source size (bits)** | **Destination size (bits)** | **Data placement** | **Comment** |
| --- | --- | --- | --- | --- |
| Rd = memub(Rs) | 8 | 32 | Low 8 bits | Zero-extend 8 to 32 bits |
| Rd = memb(Rs) | 8 | 32 | Low 8 bits | Sign-extend 8 to 32 bits |
| Rd = memuh(Rs) | 16 | 32 | Low 16 bits | Zero-extend 16 to 32 bits |
| Rd = memh(Rs) | 16 | 32 | Low 16 bits | Sign-extend 16 to 32 bits |
| Rd = memubh(Rs) | 16 | 32 | Bytes 0 and 2 | Bytes 1 and 3 zeroed [\[2\]](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#mem2) |
| Rd = membh(Rs) | 16 | 32 | Bytes 0 and 2 | Bytes 1 and 3 sign-extended |
| Rd = memw(Rs) | 32 | 32 | All 32 bits | Load word |
| Rdd = memubh(Rs) | 32 | 64 | Bytes 0,2,4,6 | Bytes 1, 3, 5, 7 zeroed |
| Rdd = membh(Rs) | 32 | 64 | Bytes 0,2,4,6 | Bytes 1, 3, 5, 7 sign-extended |
| Rdd = memd(Rs) | 64 | 64 | All 64 bits | Load doubleword |
| Ryy = memh\_fifo(Rs) | 16 | 64 | High 16 bits | Shift vector and load halfword |
| deallocframe | 64 | 64 | All 64 bits | See [Software stack](https://docs.qualcomm.com/doc/80-N2040-60/topic/software-stack.html) |
| dealloc\_return | 64 | 64 | All 64 bits | See [Software stack](https://docs.qualcomm.com/doc/80-N2040-60/topic/software-stack.html) |

[[2](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#id2)]

The memubh and membh instructions load contiguous bytes from memory
(either 2 or 4 bytes) and unpack these bytes into a vector of
halfwords. The instructions are useful when bytes are used as input
into halfword vector operations, which is common in video and image
processing..

## Memory stores

The Hexagon processor stores data to memory in byte, halfword, word, or doubleword sizes.
The syntax used is memX, where X denotes the data type. The memory store instructions belong
to the ST instruction class and can only execute in slot 0 or, when part of a dual store, slot 1.

Store instructions

| **Syntax** | **Source size (bits)** | **Destination size (bits)** | **Comment** |
| --- | --- | --- | --- |
| memb(Rs) = Rt | 32 | 8 | Store byte (bits 7:0) |
| memb(Rs) = #s8 | 8 | 8 | Store byte |
| memh(Rs) = Rt | 32 | 16 | Store lower half (bits 15:0) |
| memh(Rs) = Rt.H | 32 | 16 | Store upper half (bits 31:16) |
| memh(Rs) = #s8 | 8 | 16 | Sign-extend 8 bits to 16 bits |
| memw(Rs) = Rt | 32 | 32 | Store word |
| memw(Rs) = #s8 | 8 | 32 | Sign-extend 8 bits to 32 bits |
| memd(Rs) = Rtt | 64 | 64 | Store doubleword |
| allocframe(#u11) | 64 | 64 | See [Software stack](https://docs.qualcomm.com/doc/80-N2040-60/topic/software-stack.html) |

## Dual stores

Two memory store instructions can appear in the same instruction
packet. The store instructions in a dual store must belong to
the [ST](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#st) instruction class and can only execute in slots 0 and 1.
The resulting operation is considered a dual store. For example:

{
       memw(R5) = R2   // Dual store
       memh(R6) = R3
    }
    Copy to clipboard

Unlike most packetized operations, dual stores do not execute in
parallel ([packet execution semantics](https://docs.qualcomm.com/doc/80-N2040-60/topic/instructions.html#v79-prm-packet-execution-semantics)).
Instead, the store instruction in slot 1 effectively executes first, followed
by the store instruction in slot 0.

## slot 1 store with slot 0 load

A slot 1 store operation with a slot 0 load operation can appear in a
packet. The packet attribute `:mem_noshuf` inhibits the instruction
reordering that is otherwise done by the assembler. For example:

{
       memw(R5) = R2    // slot 1 store
       R3 = memh(R6)    // slot 0 load
    }:mem_noshuf
    Copy to clipboard

Unlike most packetized operations, these memory operations do not
execute in parallel
([packet execution semantics](https://docs.qualcomm.com/doc/80-N2040-60/topic/instructions.html#v79-prm-packet-execution-semantics)).
Instead, the store instruction in slot 1 effectively executes first,
followed by the load instruction in slot 0. If the addresses of the two
operations are overlapping, the load receives the newly stored data.

## New-value stores

A memory store instruction can store a register that is assigned a
new value in the same [instruction packet](https://docs.qualcomm.com/doc/80-N2040-60/topic/instructions.html#v79-prm-instruction-packets)).
The new-value store instructions belong to the NV instruction class and can only execute in slot 0.

Append the suffix `.new` to the source register to express this feature. For example:

{
       R2 = memh(R4+#8)    // load halfword
       memw(R5) = R2.new   // store newly-loaded value
    }
    Copy to clipboard

New-value store instructions have the following restrictions:

- If an instruction uses auto-increment or absolute-set addressing mode
([addressing modes](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-addressing-modes)), its address register
cannot be used as the new-value register.
- If an instruction produces a 64-bit result, its result registers
cannot be used as the new-value register.
- An instruction that conditionally sets the target register of a .new store is not valid.
([consuming scalar predicates](https://docs.qualcomm.com/doc/80-N2040-60/topic/conditional-execution.html#v79-prm-consuming-scalar-predicates))

{
           if (P1) R0 = sub(R2,R3)  //  R0 is conditionally set
           memw(R5) = R0.new        //  Not a valid store
        }
        Copy to clipboard

## Mem-ops

Mem-ops perform basic arithmetic, logical, and bit operations
directly on memory operands, without the need for a separate load or
store. The mem-op instructions belong to the MEMOP instruction class
and can only execute in slot 0. Mem-ops use byte, halfword, or word sizes.

Mem-ops

| **Syntax** | **Operation** |
| --- | --- |
| memXX(Rs+#u6) [+-|&] = Rt | Arithmetic/logical on memory |
| memXX(Rs+#u6) [+-] = #u5 | Arithmetic on memory |
| memXX(Rs+#u6) = clrbit(#u5) | Clear bit in memory |
| memXX(Rs+#u6) = setbit(#u5) | Set bit in memory |

## Addressing modes

Addressing modes

| **Mode** | **Syntax** | **Operation** [\[3\]](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#mem3) |
| --- | --- | --- |
| [Absolute](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-absolute) | memXX(##address) | EA = address |
| [Absolute-set](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-absolute-set) | memXX(Re=##address) | EA = address Re = address |
| [Absolute with register offset](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-absolute-with-register-offset) | memXX(Ru&lt;&lt;#u2+##U32) | EA = imm + (Ru &lt;&lt; #u2) |
| [Global pointer relative](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-global-pointer-relative) | memXX(GP+#immediate) memXX(#immediate) | EA = GP + immediate |
| [Indirect](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-indirect) | memXX(Rs) | EA = Rs |
| [Indirect with offset](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-indirect-with-offset) | memXX(Rs+#s11) | EA = Rs + imm |
| [Indirect with register offset](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-indirect-with-register-offset) | memXX(Rs+Ru&lt;&lt;#u2) | EA = Rs + (Ru &lt;&lt; #u2) |
| [Indirect with auto-increment immediate](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-indirect-with-auto-increment-immediate) | memXX(Rx++#s4) | EA = Rx;<br><br><br>Rx += (imm) |
| [Indirect with auto-increment register](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-indirect-with-auto-increment-register) | memXX(Rx++Mu) | EA = Rx;<br><br><br>Rx += Mu |
| [Circular with auto-increment immediate](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-circular-with-auto-increment-immediate) | memXX(Rx++#s4:circ(Mu)) | EA = Rx;<br><br><br>Rx = circ\_add(Rx,imm,Mu) |
| [Circular with auto-increment register](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-circular-with-auto-increment-register) | memXX(Rx++I:circ(Mu)) | EA = Rx;<br><br><br>Rx = circ\_add(Rx,I,Mu) |
| [Bit-reversed with auto-increment register](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-bit-reversed-with-auto-increment-register) | memXX(Rx++Mu:brev) | EA = Rx.H + bit\_reverse(Rx.L) Rx += Mu |

[[3](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#id3)]

EA (effective address) is equivalent to VA (virtual address).

### Absolute

The absolute addressing mode uses a 32-bit constant value as the
effective memory address. For example:

R2 = memw(##100000)   // Load R2 with word from addr 100000
    memw(##200000) = R4   // Store R4 to word at addr 200000
    Copy to clipboard

### Absolute-set

The absolute-set addressing mode assigns a 32-bit constant value to
the specified general register, then uses the assigned value as the
effective memory address. For example:

R2 = memw(R1=##400000)   // Load R2 with word from addr 400000
                             // and load R1 with value 400000
    memw(R3=##600000) = R4   // Store R4 to word at addr 600000
                             // and load R3 with value 600000
    Copy to clipboard

### Absolute with register offset

The absolute with register offset addressing mode performs an
arithmetic left shift of a 32-bit general register value by the
amount specified in a 2-bit unsigned immediate value, and then adds
the shifted result to an unsigned 32-bit constant value to create the
32-bit effective memory address. For example:

R2 = memh(R3 << #3 + ##100000)   // load R2 with signed halfword
                                     // from addr [100000 + (R3 << 3)]
    Copy to clipboard

The 32-bit constant value is the base address, and the shifted result
is the byte offset.

### Global pointer relative

The global pointer relative addressing mode adds an unsigned offset
value to the global data pointer GP to create the
32-bit effective memory address.

Global pointer relative addresses can be expressed two ways in
assembly language:

- By explicitly adding an unsigned offset value to register GP
- By specifying only an immediate value as the instruction operand

For example:

> 
> 
> R2 = memh(GP+#100)   // Load R2 with signed halfword
>                          // from [GP + 100 bytes]
>     Copy to clipboard

Specifying only an immediate value causes the assembler and linker to
automatically subtract the value of the special symbol \_SDA\_BASE\_
from the immediate value, and use the result as the effective offset
from GP.

For example:

> 
> 
> R3 = memh(#2000)     // Load R3 with signed halfword
>                          // from [GP + #2000 - \_SDA_BASE]
>     Copy to clipboard

The register field GP.GDP holds the global data pointer
([register GP](https://docs.qualcomm.com/doc/80-N2040-60/topic/registers.html#v79-prm-global-pointer)). GP.GDP contains an
unsigned 26-bit value that specifies the most significant 26 bits of
the 32-bit global data pointer. The least significant 6 bits of the
pointer are always defined as zero.

When expressed in assembly language, the immediate values used in global
pointer relative addressing always specify byte offsets from the
global data pointer. The byte offsets are integral multiples of the
size of the instruction data type. The memory area can be up to 512 kB
in length and must be aligned to a 64-byte boundary in memory.

Offset ranges (global pointer relative)

| **Data type** | **Offset range** | **Offsets are multiple of** |
| --- | --- | --- |
| doubleword | 0 … 524280 | 8 |
| word | 0 … 262140 | 4 |
| halfword | 0 … 131070 | 2 |
| byte | 0 … 65535 | 1 |

### Indirect

The indirect addressing mode uses a 32-bit value in a general
register as the effective memory address. For example:

R2 = memub(R1) // load R2 with unsigned byte from addr in R1
    Copy to clipboard

### Indirect with offset

The indirect with offset addressing mode adds an offset value
to a general register value to create the 32-bit effective memory
address. For example:

R2 = memh(R3 + #100)   // load R2 with signed halfword
                           // from [R3 + 100 bytes]
    Copy to clipboard

When expressed in assembly language, the immediate values always specify
byte offsets from the general register value. The byte offsets are
integral multiples of the size of the instruction data type.

Offset ranges indirect with offset

| **Data type** | **Signed offset range (non-conditional instructions)** | **Unsigned offset range (conditional instructions)** | **Offsets are multiple of** |
| --- | --- | --- | --- |
| doubleword | -8192 … 8184 | 0 … 504 | 8 |
| word | -4096 … 4092 | 0 … 252 | 4 |
| halfword | -2048 … 2046 | 0 … 126 | 2 |
| byte | -1024 … 1023 | 0 … 63 | 1 |

### Indirect with register offset

The indirect with register offset addressing mode adds a 32-bit
general register value to the result created by performing an
arithmetic left shift of a second 32-bit general register value by
a 2-bit unsigned immediate value, forming the32-bit effective memory
address. For example:

R2 = memh(R3+R4<<#1)   // load R2 with signed halfword
                           // from [R3 + (R4 << 1)]
    Copy to clipboard

The register values always specify byte addresses.

### Indirect with auto-increment immediate

The indirect with auto-increment immediate addressing mode uses a
32-bit value stored in a general register to specify the effective
memory address. However, after the address is accessed, a signed
value (known as the increment) is added to the register so it
specifies a different memory address (which is accessed in a
subsequent instruction). For example:

R2 = memw(R3++#4)   // R3 contains the effective address
                        // R3 is then incremented by 4
    Copy to clipboard

When expressed in assembly language, the immediate values always
specify byte increments. The byte increments are
integral multiples of the size of the instruction data type.

Increment ranges (indirect with auto-increment immediate)

| **Data type** | **Increment range** | **Increments are multiple of** |
| --- | --- | --- |
| doubleword | -64 … 56 | 8 |
| word | -32 … 28 | 4 |
| halfword | -16 … 14 | 2 |
| byte | -8 … 7 | 1 |

### Indirect with auto-increment register

The indirect with auto-increment register addressing mode is
functionally equivalent to indirect with auto-increment immediate,
but uses a modifier register Mx
([modifier registers](https://docs.qualcomm.com/doc/80-N2040-60/topic/registers.html#v79-prm-modifier-registers)) instead of
an immediate value to hold the increment. For example:

R2 = memw(R0++M1)   // The effective addr is the value of R0.
                        // Next, M1 is added to R0 and the result
                        // is stored in R0.
    Copy to clipboard

When auto-incrementing with a modifier register, the increment is a
signed 32-bit value that is added to the general register. This
offers two advantages over auto-increment immediate:

- A larger increment range
- Variable increments (because the modifier register can be programmed
at runtime).

The modifier register value always specifies a byte increment.
The signed 32-bit increment range is identical for all
instruction data types (doubleword, word, halfword, byte).

### Circular with auto-increment immediate

The circular with auto-increment immediate addressing mode is a
variant of indirect with auto- increment addressing. It accesses
data buffers in a modulo wrap around fashion.

The address modifier `:circ(Mx)` expresses circular addressing in assembly language.
`Mx` specifies a modifier register that is programmed to specify the circular buffer
length ([modifier registers](https://docs.qualcomm.com/doc/80-N2040-60/topic/registers.html#v79-prm-modifier-registers)). For example:

Rd = memb(R2++#4:circ(Mx))   // Load from circ buffer
    memw(Rs++#8:circ(Mx)) = Rt   // Store to circ buffer
    Copy to clipboard

Program the following elements to use circular addressing:

- The length field of the `Mx` register is set to the length (in bytes)
of the circular buffer to access. A circular buffer can be from 4 to
(2^17^-1) bytes long.
- Bits 27:24 of the `Mx` register are always set to 0.
- Set CSx to the start address of the circular buffer. Use CS0 and
M0 together or CS1 and M1 together.

The general register Rs specifies the effective address for the memory access.
The following equation sets the new Rs value after the memory access:

Rs = CSx + ((Rs + increment) % Mx.length)

When expressed in assembly language, the immediate values always
specify byte increments. The byte increments are integral multiples
of the size of the instruction data type.

Increment ranges (circular with auto-increment immediate addressing

| **Data type** | **Increment range** | **Increments are multiple of** |
| --- | --- | --- |
| doubleword | -64 … 56 | 8 |
| word | -32 … 28 | 4 |
| halfword | -16 … 14 | 2 |
| byte | -8 … 7 | 1 |

Following this set of rules prevents undefined behavior:

- The start address must be aligned to the native access size of the
buffer elements.
- The absolute value of the increment must be less than the buffer length.
- The memory access size (1 for byte, 2 for
halfword, 4 for word, 8 for doubleword) must be less than (Length-1).
- Buffers must not wrap around in the 32-bit address space.

The following example sets up and accesses a 150-byte circular
buffer:

R4.H = #0 // M0[27:24]= 0x0
    R4.L = #150 // length = 150
    M0 = R4
    R2 = ##cbuf                    // start addr = cbuf
    CS0 = R2
    R0 = memb(R2++#4:circ(M0))     // Load byte from circ buf
                                   // specified by M0/CS0
                                   // inc R2 by 4 after load
                                   // wrap R2 around if >= 150
    Copy to clipboard

### Circular with auto-increment register

The circular with auto-increment register addressing mode is
functionally equivalent to circular with auto-increment immediate,
but uses a register instead of an immediate value to hold the
increment.

Register increments are specified in circular addressing instructions
by using the symbol I as the increment (instead of an immediate
value). For example:

Rd = memw(Rs++I:circ(Mx))   // Load byte with incr of I*4 from
                                // circ buf specified by Mx/CSx
    Copy to clipboard

When auto-incrementing with a register, the increment is a signed 11-bit
value that is added to the general register. The field Mx.I
([modifier registers](https://docs.qualcomm.com/doc/80-N2040-60/topic/registers.html#v79-prm-modifier-registers)) holds the
signed 11-bit increment value. Compared to circular addressing
with immediate increments, auto-incrementing with a register allows
for larger increment ranges and variable increments.

When expressed in assembly language, the Mx.I value always specifies byte increments.
The byte increments are integral multiples of the size of the instruction data type.

Increment ranges (circular with auto-increment register addressing)

| **Data type** | **Increment range** | **Increments are multiple of** |
| --- | --- | --- |
| doubleword | -8192 … 8184 | 8 |
| word | -4096 … 4092 | 4 |
| halfword | -2048 … 2046 | 2 |
| byte | -1024 … 1023 | 1 |

### Bit-reversed with auto-increment register

The bit-reversed with auto-increment register addressing mode is a
variant of indirect with auto- increment addressing - it accesses
data buffers using an address value that is the bit-wise reversal of
the value stored in the general register.

The following defines bit-wise reversal of a 32-bit address value:

- The lower 16 bits are transformed by exchanging bit 0 with bit 15,
bit 1 with bit 14, and so on.
- The upper 16 bits remain unchanged.

The address modifier `brev` expresses bit-reversed addressing in assembly language.

For example:

Rd = memub(Rs++Mx:brev)   // The address is (Rs.H \| bitrev(Rs.L))
                              // The original Rs (not reversed) is added
                              // to Mx and written back to Rs
    Copy to clipboard

The initial values for the address and increment must be set in
bit-reversed form with the hardware bit-reversing the bit-reversed
address value to form the effective address.

The buffer length for a bit-reversed buffer must be an integral power
of 2 with a maximum length of 64K bytes.

To support bit-reversed addressing, buffers must be properly aligned
in memory. A bit-reversed buffer is properly aligned when its
starting byte address is aligned to a power of 2 greater than or
equal to the buffer size (in bytes). For example:

int bitrev_buf[256] attribute ((aligned(1024)));
    Copy to clipboard

The bit-reversed buffer declared above is aligned to 1024 bytes
because the buffer size is 1024 bytes (256 integer words x 4 bytes),
and 1024 is an integral power of 2.

The buffer location pointer for a bit-reversed buffer must be
initialized so thatthe least-significant 16 bits of the address value
are bit-reversed.

The increment value must be initialized to the following value:

bitreverse(buffer_size_in_bytes / 2)
    Copy to clipboard

where bitreverse is defined as bit-reversing the least-significant
16 bits while leaving the remaining bits unchanged.

Note

To simplify the initialization of the bit-reversed pointer,
align bit-reversed buffers to a 64K byte boundary. This
initializes the bit-reversed pointer to the base address of the
buffer, with no bit-reversing required for the
least-significant 16 bits of the pointer value which
the 64K alignment sets to 0).

After a bit-reversed memory access completes, the general register
increments by the increment value. The bit-reversal that is
performed as part of the memory access never affects the value
in the general register.

Note

The Hexagon processor only supports register increments for
bit-reversed addressing. It does not support immediate increments.

## Conditional load/stores

The compiler generates conditional loads and stores to increase instruction-level parallelism.
Some load and store instructions can be executed conditionally based
on predicate values that were set in a previous instruction.

The instruction prefix `if (pred_expr)` expresses conditional loads and stores in assembly language,
where `pred_expr` specifies a predicate register expression ([scalar predicates](https://docs.qualcomm.com/doc/80-N2040-60/topic/conditional-execution.html#v79-prm-scalar-predicates)).
For example:

if (P0) R0 = memw(R2)            // Conditional load
    if (!P2) memh(R3 + #100) = R1    // Conditional store
    if (P1.new) R3 = memw(R3++#4)    // Conditional load
    Copy to clipboard

Condtional loads and stores do not support all addressing modes.
[Addressing modes (conditional load/store)](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-tbl-addressing-modes-conditional-load-store)
shows the supported modes.

Condtional load/store addressing modes

| **Addressing mode** | **Conditional** |
| --- | --- |
| Absolute | Yes |
| Absolute-set | No |
| Absolute with register offset | No |
| Global pointer relative | No |
| Indirect | Yes |
| Indirect with offset | Yes |
| Indirect with register offset | Yes |
| Indirect with auto-increment immediate | Yes |
| Indirect with auto-increment register | No |
| Circular with auto-increment immediate | No |
| Circular with auto-increment register | No |
| Bit-reversed with auto-increment register | No |

When a conditional load or store instruction uses
[Indirect with offset](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#v79-prm-indirect-with-offset) addressing mode, the
offset range is smaller than the range normally defined for indirect-with-offset
addressing.

Conditional and non-conditional offset ranges (indirect with offset addressing)

| **Data type** | **Offset range (conditional)** | **Offset range (non-conditional)** | **Offsets are multiple of** |
| --- | --- | --- | --- |
| doubleword | 0 … 504 | -8192 … 8184 | 8 |
| word | 0 … 252 | -4096 … 4092 | 4 |
| halfword | 0 … 126 | -2048 … 2046 | 2 |
| byte | 0 … 63 | -1024 … 1023 | 1 |

Note

For more information on conditional execution, see
[Conditional execution](https://docs.qualcomm.com/doc/80-N2040-60/topic/conditional-execution.html).

## Cache memory

The Hexagon processor has a cache-based memory architecture:

- A level 1 instruction cache holds recently fetched instructions.
- A level 1 data cache holds recently accessed data memory.

Loads/stores that access memory through the level 1 caches
are cached accesses.

Loads/stores that bypass the level 1 caches are uncached accesses.

The memory management unit (MMU) of the Hexagon processor can
configure specific memory pages as cached or uncached.

Hexagon supports two types of caching:

- Write-through caching keep the cache data consistent with external
memory.
- Writeback caching stores data in the cache without writing to external memory
immediately. Cached data that is inconsistent with
external memory is referred to as dirty.

### Uncached memory

In some cases, load/store operations bypass the cache memories
and are serviced externally. For example, accessing memory-mapped
I/O, registers, and peripheral devices, or other system defined
entities.

Hexagon catgorizes uncached memory as two distinct types:

- Device-type is for accessing addresses that have side-effects such as a
memory-mapped FIFO peripheral. The hardware ensures that interrupts
do not cancel a pending device access. The hardware does not reorder
device accesses. Mark peripheral control registers as device-type.
- Uncached-type is for memory-like addresses where no side effects are
associated with an access. The hardware can load from uncached memory
multiple times and can reorder uncached accesses.

Device-type memory is functionally identical to uncached-type memory
for instruction fetches.

### Tightly coupled memory

The Hexagon processor supports tightly coupled instruction memory at
level 1, which is defined as memory with similar access properties to
the instruction cache.

Tightly coupled memory also implements a level 2 cache, which is defined
as backing store to the level 1 caches.

### Cache maintenance operations

The Hexagon processor includes dedicated cache maintenance
instructions that invalidate cache data or push dirty data out to
external memory.

The cache maintenance instructions operate on specific memory
addresses. If the instruction causes an address error (due to a
privilege violation), the processor raises an exception. The
exception to this rule is the `dcfetch` operation, which never causes
a processor exception.

Cache instructions (user-level)

| **Syntax** | **Permitted in packet** | **Operation** |
| --- | --- | --- |
| icinva(Rs) | Solo [\[4\]](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#mem4) | Instruction cache invalidate.<br><br><br>Look up instruction cache at address Rs. If the address is<br>in the cache, invalidate it. |
| dccleaninva(Rs) | slot 1 empty or ALU32 only | Data cache clean and invalidate.<br><br><br>Look up data cache at address Rs.<br><br><br>If the address is in the cache and has dirty data, flush<br>that data out to memory. The cache line is then invalidated,<br>whether or not dirty data was written. |
| dccleana(Rs) | slot 1 empty or ALU32 only | Data cache clean.<br><br><br>Look up data cache at address Rs.<br><br><br>If the address is in the cache and has dirty data, flush<br>that data out to memory. |
| dcinva(Rs) | slot 1 empty or ALU32 only | Maps to dccleaninva(Rs). |
| dcfetch(Rs) | Normal [\[5\]](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#mem5) | Data cache prefetch.<br><br><br>Prefetch data at address Rs into the data cache.<br><br><br>Note<br><br><br>This instruction does not cause an exception. |
| l2fetch(Rs,Rt) | ALU32 or<br><br><br>XTYPE only | L2 cache prefetch.<br><br><br>Prefetch data from memory specified by Rs and Rt into L2<br>cache. |

[[4](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#id4)]

*Solo* means that the instruction must not be grouped with other
instructions in a packet.

[[5](https://docs.qualcomm.com/doc/80-N2040-60/topic/memory.html#id5)]

*Normal* means that the normal instruction-grouping constraints
apply.

The data cache coherency operations (including clean, invalidate, and
clean and invalidate) affect both the L1 and L2 caches, and ensure
that the memory hierarchy remains coherent.

However, the instruction cache invalidate operation affects only the
L1 cache. Therefore, invalidating instructions that might be in the
L1 or L2 caches requires a two-step procedure:

1. Use icinva to invalidate instructions from the L1 cache.
2. Use dcinva separately to invalidate instructions from the L2 cache.

### Cache line zero

The Hexagon processor includes the instruction `dczeroa`. This
instruction allocates a line in the L1 data cache and clears it
by setting the line to zero. The `dczeroa` operation has the
same exception behavior as write-back stores. A packet with `dczeroa`
must have slot 1 either empty or containing an ALU32 instruction.

The behavior is as follows:

- The Rs register value must be 32-byte aligned. If it is unaligned,
the processor raises an unaligned error exception.
- For a cache hit, the data cache clears the specified cache line and marks it dirty.
- For a cache miss, the data cache does not fetch the specified cache line from
external memory. Instead, the data cache allocates the line,
clears the line, and marks it dirty.

### Cache prefetch types supported by the Hexagon processor

#### Hardware-based instruction cache prefetching

The USR.HFI ([User status register](https://docs.qualcomm.com/doc/80-N2040-60/topic/registers.html#v79-prm-user-status-register))
enables instruction cache prefetching on a per-hardware thread basis.

#### Software-based data cache prefetching

The Hexagon processor includes the `dcfetch` instruction, which queries
the L1 data cache based on the address specified in the instruction:

- If the address is present in the cache, no action is taken.
- If the cache line for the address is missing, the processor attempts
to fill the cache line from the next level of memory. The thread does
not stall, but rather continues executing while the cache line fill
occurs in the background.
- If the address is invalid, no exception is generated and the `dcfetch`
instruction is treated as a NOP.

#### Software-based l2fetch

The `l2fetch` instruction initiates background prefetch of code or
data into the L2 cache. There are two forms of this instruction.

In the first form, Rs,Rt specify the start address and dimensions
of the area to prefetch as follows:

- Rs specifies the 32-bit virtual start address.
- Rt[15:8] = Width of a fetch block in bytes.
- Rt[7:0] = Height: the number of width-sized blocks to fetch.
- Rt[31:16] = Stride: an unsigned byte offset added to the pointer after fetching each width-sized block.

In the second form, Rs,Rtt specify the start address and dimensions of the area to prefetch as follows:

- Rs specifies the 32-bit virtual start address.
- Rtt[31:16] = Width of a fetch block in bytes.
- Rtt[15:0] = Height: the number of width-sized blocks to fetch.
- Rtt[47:32] = Stride: an unsigned byte offset added to the pointer after fetching each width-sized block.
- Rtt[48] = Direction. If 0, prefetches in row-major order.
All cache lines in a row are fetched before proceeding to the next row.
If 1, prefetches in column-major order. All cache lines in a column are fetched before proceeding to the next column.

The following figure shows two examples of using the `l2fetch` instruction:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by Microsoft Visio, SVG Export pic_l2fetch.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="5.48973in" height="3.79991in" viewbox="0 0 395.261 273.594" xml:space="preserve" color-interpolation-filters="sRGB" class="st12"><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvConvertTheme"></v:ud>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-2 .st1 { fill: none; stroke: #2a2aea; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.2 }
.svg-2 .st2 { fill: #2a2aea; font-family: Roboto; font-size: 0.75em }
.svg-2 .st3 { fill: none; stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.2 }
.svg-2 .st4 { font-size: 1em }
.svg-2 .st5 { marker-end: url("#mrkr5-30"); marker-start: url("#mrkr5-28"); stroke: #2a2aea; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.2 }
.svg-2 .st6 { fill: #2a2aea; fill-opacity: 1; stroke: #2a2aea; stroke-opacity: 1; stroke-width: 0.32258064516129 }
.svg-2 .st7 { marker-end: url("#mrkr4-56"); stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.239976 }
.svg-2 .st8 { fill: #000000; fill-opacity: 1; stroke: #000000; stroke-opacity: 1; stroke-width: 0.11763667807857 }
.svg-2 .st9 { marker-end: url("#mrkr4-85"); stroke: #2a2aea; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.239976 }
.svg-2 .st10 { fill: #2a2aea; fill-opacity: 1; stroke: #2a2aea; stroke-opacity: 1; stroke-width: 0.11763667807857 }
.svg-2 .st11 { marker-start: url("#mrkr5-28"); stroke: #2a2aea; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.2 }
.svg-2 .st12 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<defs id="Markers">	<g id="lend5">		<path d="M 2 1 L 0 0 L 1.98117 -0.993387 C 1.67173 -0.364515 1.67301 0.372641 1.98465 1.00043 " style="stroke:none"></path>	</g>	<marker id="mrkr5-28" class="st6" v:arrowtype="5" v:arrowsize="2" v:setback="5.125" refx="5.125" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend5" transform="scale(3.1) "></use>	</marker>	<marker id="mrkr5-30" class="st6" v:arrowtype="5" v:arrowsize="2" v:setback="5.425" refx="-5.425" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend5" transform="scale(-3.1,-3.1) "></use>	</marker>	<g id="lend4">		<path d="M 2 1 L 0 0 L 2 -1 L 2 1 " style="stroke:none"></path>	</g>	<marker id="mrkr4-56" class="st8" v:arrowtype="4" v:arrowsize="1" v:setback="17.0015" refx="-17.001500150015" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend4" transform="scale(-8.5007500750075,-8.5007500750075) "></use>	</marker>	<marker id="mrkr4-85" class="st10" v:arrowtype="4" v:arrowsize="1" v:setback="17.0015" refx="-17.001500150015" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend4" transform="scale(-8.5007500750075,-8.5007500750075) "></use>	</marker></defs><g v:mid="5" v:index="1" v:groupcontext="foregroundPage">	<title>Page-1</title>	<v:pageproperties v:drawingscale="0.0393701" v:pagescale="0.0393701" v:drawingunits="24" v:shadowoffsetx="8.50394" v:shadowoffsety="-8.50394"></v:pageproperties>	<v:layer v:name="Connector" v:index="0"></v:layer>	<g id="shape4-1" v:mid="4" v:groupcontext="shape" transform="translate(31.3559,-18.6)">		<title>Rectangle.4</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<rect x="0" y="171.546" width="161.575" height="102.047" class="st1"></rect>	</g>	<g id="shape1-3" v:mid="1" v:groupcontext="shape" transform="translate(39.8598,-159.12)">		<title>Rectangle</title>		<desc>Start address</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="60.2362" cy="262.255" width="120.48" height="22.6772"></v:textrect>		<rect x="0" y="250.917" width="120.472" height="22.6772" class="st1"></rect>		<text x="33.47" y="264.96" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Start address</text>		</g>	<g id="shape2-6" v:mid="2" v:groupcontext="shape" transform="translate(40.5685,-197.387)">		<title>Rectangle.2</title>		<desc>Stride</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="29.7638" cy="262.255" width="59.53" height="22.6772"></v:textrect>		<rect x="0" y="250.917" width="59.5276" height="22.6772" class="st1"></rect>		<text x="18.09" y="264.96" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Stride</text>		</g>	<g id="shape9-9" v:mid="9" v:groupcontext="shape" transform="translate(18.6,-162.458)">		<title>Sheet.9</title>		<desc>Rs</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="10.126" cy="265.594" width="20.26" height="16"></v:textrect>		<rect x="0" y="257.594" width="20.252" height="16" class="st3"></rect>		<text x="5.04" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Rs</text>		</g>	<g id="shape10-12" v:mid="10" v:groupcontext="shape" transform="translate(89.4661,-127.734)">		<title>Sheet.10</title>		<desc>Stride</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="31.2126" cy="265.594" width="62.43" height="16"></v:textrect>		<rect x="0" y="257.594" width="62.4252" height="16" class="st3"></rect>		<text x="19.54" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Stride</text>		</g>	<g id="shape140-15" v:mid="140" v:groupcontext="shape" transform="translate(27.9858,-238.994)">		<title>Sheet.140</title>		<desc>L2FETCH for box prefetch</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="73.2598" cy="265.594" width="146.52" height="16"></v:textrect>		<rect x="0" y="257.594" width="146.52" height="16" class="st3"></rect>		<text x="21.45" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>L2FETCH for box prefetch</text>		</g>	<g id="shape3-18" v:mid="3" v:groupcontext="shape" transform="translate(79.5449,-49.7811)">		<title>Rectangle.3</title>		<desc>Prefetch area</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="25.5118" cy="253.694" width="51.03" height="39.7984"></v:textrect>		<rect x="0" y="233.795" width="51.0236" height="39.7984" class="st1"></rect>		<text x="8.52" y="250.99" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Prefetch <tspan x="16.71" dy="1.2em" class="st4">area</tspan></text>		</g>	<g id="shape5-22" v:mid="5" v:groupcontext="shape" v:layermember="0" transform="translate(131.986,-89.4661)">		<title>Dynamic connector.5</title>		<path d="M-6.15 266.51 L-6.51 266.51 L-45.93 266.51" class="st5"></path>	</g>	<g id="shape7-31" v:mid="7" v:groupcontext="shape" v:layermember="0" transform="translate(63.9543,-49.7811)">		<title>Dynamic connector.7</title>		<path d="M0.94 273.59 L0.58 273.59 L-6.31 273.59 L-6.31 233.8 L0.58 233.8" class="st5"></path>	</g>	<g id="shape11-38" v:mid="11" v:groupcontext="shape" v:layermember="0" transform="translate(191.513,-120.647)">		<title>Dynamic connector.11</title>		<path d="M0 260.36 L0 260 L0 245.17 L-161.57 245.17 L-161.57 260" class="st5"></path>	</g>	<g id="shape6-45" v:mid="6" v:groupcontext="shape" transform="translate(73.8441,-94.222)">		<title>Sheet.6</title>		<desc>Width</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="31.2126" cy="265.594" width="62.43" height="16"></v:textrect>		<rect x="0" y="257.594" width="62.4252" height="16" class="st3"></rect>		<text x="19.64" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Width</text>		</g>	<g id="shape12-48" v:mid="12" v:groupcontext="shape" transform="translate(25.6866,-61.6803)">		<title>Sheet.12</title>		<desc>Height</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="31.2126" cy="265.594" width="62.43" height="16"></v:textrect>		<rect x="0" y="257.594" width="62.4252" height="16" class="st3"></rect>		<text x="18.06" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Height</text>		</g>	<g id="shape8-51" v:mid="8" v:groupcontext="shape" v:layermember="0" transform="translate(361.405,163.836) rotate(100.394)">		<title>Directed line 1</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>			<v:ud v:nameu="msvThemeEffects" v:prompt="" v:val="VT0(1):26"></v:ud>		</v:userdefs>		<path d="M0 273.59 L66.62 273.59" class="st7"></path>	</g>	<g id="shape14-57" v:mid="14" v:groupcontext="shape" transform="translate(100.096,-197.387)">		<title>Rectangle.14</title>		<desc>Width</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="16.6535" cy="262.255" width="33.31" height="22.6772"></v:textrect>		<rect x="0" y="250.917" width="33.3071" height="22.6772" class="st1"></rect>		<text x="5.08" y="264.96" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Width</text>		</g>	<g id="shape15-60" v:mid="15" v:groupcontext="shape" transform="translate(133.403,-197.387)">		<title>Rectangle.15</title>		<desc>Height</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="17.4331" cy="262.255" width="34.87" height="22.6772"></v:textrect>		<rect x="0" y="250.917" width="34.8661" height="22.6772" class="st1"></rect>		<text x="4.28" y="264.96" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Height</text>		</g>	<g id="shape13-63" v:mid="13" v:groupcontext="shape" transform="translate(18.6,-200.726)">		<title>Sheet.13</title>		<desc>Rt</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="10.126" cy="265.594" width="20.26" height="16"></v:textrect>		<rect x="0" y="257.594" width="20.252" height="16" class="st3"></rect>		<text x="5.89" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Rt</text>		</g>	<g id="shape16-66" v:mid="16" v:groupcontext="shape" transform="translate(268.944,-107.797)">		<title>Rectangle.16</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<rect x="0" y="265.294" width="69.4488" height="8.29921" class="st1"></rect>	</g>	<g id="shape17-68" v:mid="17" v:groupcontext="shape" transform="translate(242.015,-158.82)">		<title>Rectangle.17</title>		<desc>Start address</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="60.2362" cy="262.255" width="120.48" height="22.6772"></v:textrect>		<rect x="0" y="250.917" width="120.472" height="22.6772" class="st1"></rect>		<text x="33.47" y="264.96" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Start address</text>		</g>	<g id="shape18-71" v:mid="18" v:groupcontext="shape" transform="translate(242.724,-197.088)">		<title>Rectangle.18</title>		<desc>128</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="29.7638" cy="262.255" width="59.53" height="22.6772"></v:textrect>		<rect x="0" y="250.917" width="59.5276" height="22.6772" class="st1"></rect>		<text x="22.18" y="264.96" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>128</text>		</g>	<g id="shape19-74" v:mid="19" v:groupcontext="shape" transform="translate(220.755,-162.159)">		<title>Sheet.19</title>		<desc>Rs</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="10.126" cy="265.594" width="20.26" height="16"></v:textrect>		<rect x="0" y="257.594" width="20.252" height="16" class="st3"></rect>		<text x="5.04" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Rs</text>		</g>	<g id="shape21-77" v:mid="21" v:groupcontext="shape" transform="translate(230.141,-238.695)">		<title>Sheet.21</title>		<desc>L2FETCH for large linear prefetch</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="73.2598" cy="265.594" width="146.52" height="16"></v:textrect>		<rect x="0" y="257.594" width="146.52" height="16" class="st3"></rect>		<text x="6.66" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>L2FETCH for large linear prefetch</text>		</g>	<g id="shape28-80" v:mid="28" v:groupcontext="shape" v:layermember="0" transform="translate(534.252,246.497) rotate(118.781)">		<title>Directed line 1.28</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>			<v:ud v:nameu="msvThemeEffects" v:prompt="" v:val="VT0(1):26"></v:ud>		</v:userdefs>		<path d="M0 273.59 L44.67 273.59" class="st9"></path>	</g>	<g id="shape29-86" v:mid="29" v:groupcontext="shape" transform="translate(302.251,-197.088)">		<title>Rectangle.29</title>		<desc>128</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="15.5906" cy="262.255" width="31.19" height="22.6772"></v:textrect>		<rect x="0" y="250.917" width="31.1811" height="22.6772" class="st1"></rect>		<text x="8.01" y="264.96" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>128</text>		</g>	<g id="shape30-89" v:mid="30" v:groupcontext="shape" transform="translate(333.246,-197.088)">		<title>Rectangle.30</title>		<desc>Lines</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="15.5906" cy="262.255" width="31.19" height="22.6772"></v:textrect>		<rect x="0" y="250.917" width="31.1811" height="22.6772" class="st1"></rect>		<text x="4.89" y="264.96" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Lines</text>		</g>	<g id="shape31-92" v:mid="31" v:groupcontext="shape" transform="translate(220.755,-200.427)">		<title>Sheet.31</title>		<desc>Rt</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="10.126" cy="265.594" width="20.26" height="16"></v:textrect>		<rect x="0" y="257.594" width="20.252" height="16" class="st3"></rect>		<text x="5.89" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Rt</text>		</g>	<g id="shape23-95" v:mid="23" v:groupcontext="shape" transform="translate(160.332,-215.813)">		<title>Sheet.23</title>		<desc>0</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="7.08661" cy="265.594" width="14.18" height="16"></v:textrect>		<rect x="0" y="257.594" width="14.1732" height="16" class="st3"></rect>		<text x="4.56" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>0</text>		</g>	<g id="shape25-98" v:mid="25" v:groupcontext="shape" transform="translate(129.151,-215.813)">		<title>Sheet.25</title>		<desc>7</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="7.08661" cy="265.594" width="14.18" height="16"></v:textrect>		<rect x="0" y="257.594" width="14.1732" height="16" class="st3"></rect>		<text x="4.56" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>7</text>		</g>	<g id="shape27-101" v:mid="27" v:groupcontext="shape" transform="translate(123.034,-215.813)">		<title>Sheet.27</title>		<desc>8</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="7.08661" cy="265.594" width="14.18" height="16"></v:textrect>		<rect x="0" y="257.594" width="14.1732" height="16" class="st3"></rect>		<text x="4.56" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>8</text>		</g>	<g id="shape36-104" v:mid="36" v:groupcontext="shape" transform="translate(96.0213,-215.813)">		<title>Sheet.36</title>		<desc>15</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="10.126" cy="265.594" width="20.26" height="16"></v:textrect>		<rect x="0" y="257.594" width="20.252" height="16" class="st3"></rect>		<text x="5.07" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>15</text>		</g>	<g id="shape37-107" v:mid="37" v:groupcontext="shape" transform="translate(81.9701,-215.813)">		<title>Sheet.37</title>		<desc>16</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="10.126" cy="265.594" width="20.26" height="16"></v:textrect>		<rect x="0" y="257.594" width="20.252" height="16" class="st3"></rect>		<text x="5.07" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>16</text>		</g>	<g id="shape38-110" v:mid="38" v:groupcontext="shape" transform="translate(36.3165,-216.82)">		<title>Sheet.38</title>		<desc>31</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="10.126" cy="265.594" width="20.26" height="16"></v:textrect>		<rect x="0" y="257.594" width="20.252" height="16" class="st3"></rect>		<text x="5.07" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>31</text>		</g>	<g id="shape39-113" v:mid="39" v:groupcontext="shape" transform="translate(355.401,-216.222)">		<title>Sheet.39</title>		<desc>0</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="7.08661" cy="265.594" width="14.18" height="16"></v:textrect>		<rect x="0" y="257.594" width="14.1732" height="16" class="st3"></rect>		<text x="4.56" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>0</text>		</g>	<g id="shape40-116" v:mid="40" v:groupcontext="shape" transform="translate(328.994,-216.317)">		<title>Sheet.40</title>		<desc>7</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="7.08661" cy="265.594" width="14.18" height="16"></v:textrect>		<rect x="0" y="257.594" width="14.1732" height="16" class="st3"></rect>		<text x="4.56" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>7</text>		</g>	<g id="shape41-119" v:mid="41" v:groupcontext="shape" transform="translate(321.739,-216.222)">		<title>Sheet.41</title>		<desc>8</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="7.08661" cy="265.594" width="14.18" height="16"></v:textrect>		<rect x="0" y="257.594" width="14.1732" height="16" class="st3"></rect>		<text x="4.56" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>8</text>		</g>	<g id="shape42-122" v:mid="42" v:groupcontext="shape" transform="translate(298.176,-216.222)">		<title>Sheet.42</title>		<desc>15</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="10.126" cy="265.594" width="20.26" height="16"></v:textrect>		<rect x="0" y="257.594" width="20.252" height="16" class="st3"></rect>		<text x="5.07" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>15</text>		</g>	<g id="shape43-125" v:mid="43" v:groupcontext="shape" transform="translate(284.125,-216.222)">		<title>Sheet.43</title>		<desc>16</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="10.126" cy="265.594" width="20.26" height="16"></v:textrect>		<rect x="0" y="257.594" width="20.252" height="16" class="st3"></rect>		<text x="5.07" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>16</text>		</g>	<g id="shape44-128" v:mid="44" v:groupcontext="shape" transform="translate(235.405,-217.23)">		<title>Sheet.44</title>		<desc>31</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="10.126" cy="265.594" width="20.26" height="16"></v:textrect>		<rect x="0" y="257.594" width="20.252" height="16" class="st3"></rect>		<text x="5.07" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>31</text>		</g>	<g id="shape22-131" v:mid="22" v:groupcontext="shape" transform="translate(210.897,-59.9071)">		<title>Sheet.22</title>		<desc>128 × Lines</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:tabspace="42.5197"></v:textblock>		<v:textrect cx="29.7638" cy="265.594" width="59.53" height="16"></v:textrect>		<rect x="0" y="257.594" width="59.5276" height="16" class="st3"></rect>		<text x="6.86" y="268.29" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>128 × Lines</text>		</g>	<g id="shape32-134" v:mid="32" v:groupcontext="shape" transform="translate(268.944,-99.3953)">		<title>Rectangle.32</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<rect x="0" y="265.294" width="69.4488" height="8.29921" class="st1"></rect>	</g>	<g id="shape33-136" v:mid="33" v:groupcontext="shape" transform="translate(268.944,-91.2457)">		<title>Rectangle.33</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<rect x="0" y="265.294" width="69.4488" height="8.29921" class="st1"></rect>	</g>	<g id="shape34-138" v:mid="34" v:groupcontext="shape" transform="translate(268.944,-82.8441)">		<title>Rectangle.34</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<rect x="0" y="265.294" width="69.4488" height="8.29921" class="st1"></rect>	</g>	<g id="shape45-140" v:mid="45" v:groupcontext="shape" transform="translate(268.944,-74.4425)">		<title>Rectangle.45</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<rect x="0" y="265.294" width="69.4488" height="8.29921" class="st1"></rect>	</g>	<g id="shape46-142" v:mid="46" v:groupcontext="shape" transform="translate(268.944,-66.2929)">		<title>Rectangle.46</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(12):26"></v:ud>		</v:userdefs>		<rect x="0" y="265.294" width="69.4488" height="8.29921" class="st1"></rect>	</g>	<g id="shape20-144" v:mid="20" v:groupcontext="shape" v:layermember="0" transform="translate(249.654,-75.9071)">		<title>Dynamic connector.20</title>		<path d="M-7.06 267.44 L-7.06 267.08 L-7.06 232.9 L-7.12 232.9" class="st11"></path>	</g></g>
</svg>

**Figure 5-2 L2fetch instruction**

In the box prefetch, a 2-D range of memory is defined within a larger frame.
The second example shows prefetch for a large linear area of memory which has size Lines \* 128.

The `l2fetch` instruction is non-blocking. After the instruction is initiated, the
program continues to the next instruction while prefetching occurs in the background.
If and only if the lines are missing from the L2 cache, the hardware attempts to fetch them from the system memory.

The hardware prefetch engine requests all lines in the programmed memory
range and prefetches at a lower priority than demand fetches.
This prevents prefetch from adding traffic while the system is under heavy load.
If a program initiates an `l2fetch` while an older `l2fetch` request is pending,
the new request is queued, up to 3 deep. If 3 `l2fetch` requests are pending,
the next `l2fetch` stalls the hardware thread until the oldest request is complete.

During the time an `l2fetch` is active for a thread, USR.PFA==1 indicates that prefetches are in progress.

Executing an `l2fetch` with any subfield programmed as zero cancels all pending prefetches by the calling thread.

The implementation may drop prefetches.

#### Hardware-based data cache prefetching

L1 data cache prefetching is enabled or disabled on a per-thread
basis by setting USR.HFD
[User status register](https://docs.qualcomm.com/doc/80-N2040-60/topic/registers.html#v79-prm-user-status-register).

When data cache prefetching is enabled, the Hexagon processor
observes patterns of data cache misses and attempts to predict
future misses based on any recurring patterns of misses where the
addresses are separated by a constant stride. If such patterns are
found, the processor attempts to automatically prefetch future cache
lines.

Data cache prefetching is user-enabled at four levels:

- HFD = 00: No prefetching
- HFD = 01: Prefetch up to four lines for misses originating from a
load, with a post-update addressing mode that occurs within a
hardware loop
- HFD = 10: Prefetch up to four lines for misses originating from loads
that occur within a hardware loop
- HFD = 11: Prefetch up to eight lines for misses originating from
loads

## Memory ordering

Some devices might require synchronization of loads and stores.
In this case, a set of processor instructions
enable programmer control of the synchronization and ordering of
memory accesses. These are all solo user instructions and must
be the only one in the packet; otherwise, the behavior is undefined.

Memory ordering instructions

| **Syntax** | **Operation** |
| --- | --- |
| isync | Instruction synchronize.<br><br><br>Ensures that the modifications of TLB, SSR, and SYSCFG are visible to other threads.<br><br><br>It must be issued as follows:<br><ul class="simple"><br><li><p>After modifying the TLB</p></li><br><li><p>After changing the SSR register</p></li><br><li><p>After changing the SYSCFG register</p></li><br><li><p>After changing the STID register</p></li><br></ul> |
| syncht | Global synchronization operation.<br><br><br>This instruction ensures that all currently outstanding memory transactions from<br>all threads have completed and are globally observable before continuing past this instruction. |
| barrier | Set memory barrier.<br><br><br>Consistency domain synchronization operation.<br><br><br>This instruction ensures that currently outstanding scalar loads,<br>scalar stores, and cache operations from all threads within a consistency<br>domain have completed and are globally observable before continuing past this instruction. |

The Hexagon processor treats data memory accesses and program memory accesses
separately and holds them in separate caches. Software must ensure
coherency between data and program code when necessary.

For example, with generated or self-modified code, the modified code
in the data cache can be inconsistent with the program
cache. The software must explicitly force modified data cache lines
to memory either by using a write-through policy, or through
explicit cache clean instructions. Use a barrier instruction to
ensure completion of the stores. Finally, invalidate relevant
instruction cache contents in order to refetch the new instructions.

## Atomic operations

The Hexagon processor includes a load locked / store conditional
(LL/SC) mechanism to provide the atomic read-modify-write operation
that is necessary to implement synchronization primitives such as
semaphores and mutexes.

These primitives synchronize the execution of different software
programs running concurrently on the Hexagon processor. They can also
provide atomic memory support between the Hexagon processor and
external blocks.

Atomic instructions

| **Syntax** | **Description** |
| --- | --- |
| Rd = memw\_locked(Rs) | Load locked word.<br><br><br>Reserve lock on word at address Rs. |
| memw\_locked(Rs,Pd) = Rt | Store conditional word.<br><br><br>If no other atomic operation has been performed at the<br>address (that is, atomicity is ensured), perform the store<br>to the word at address Rs and return TRUE in Pd; otherwise<br>return FALSE.<br><br><br>TRUE indicates that the LL and SC operations were performed<br>atomically. |
| Rdd = memd\_locked(Rs) | Load locked doubleword.<br><br><br>Reserve lock on doubleword at address Rs. |
| memd\_locked(Rs,Pd) = Rtt | Store conditional doubleword.<br><br><br>If no other atomic operation has been performed at the<br>address (that is, atomicity is ensured), perform the store<br>to the doubleword at address Rs and return TRUE in Pd;<br>otherwise return FALSE.<br><br><br>TRUE indicates that the LL and SC operations have been<br>performed atomically. |

The recommended instruction sequence to acquire a spinlock is:

// Assume address is held in R0
    // Assume R1,R3,P0,P1 are scratch
    spinlock_lock:
       R3 = #1
    lock_test_spin:
       R1 = memw_locked(R0)            // Do normal test to wait
       P1 = cmp.eq(R1,#0)              // for lock to be available
       if (!P1) jump lock_test_spin
       memw_locked(R0,P0) = r3         // Do store conditional (SC)
       if (!P0) jump lock_test_spin    // was LL and SC done atomically?
    Copy to clipboard

The recommended instruction sequence to release a spinlock is:

// Assume address is held in R0
    // Assume R1 is scratch
    spinlock unlock:
       R1 = #0
       memw(R0) = R1
    Copy to clipboard

Use cacheable memory to synchronize software threads within Hexagon processor.
To perform LL/SC operations with external memory the page attribute must be set to uncached.
Otherwise the behavior is undefined. If software performs a load locked operation
to an address that does not support atomic operations the behavior is undefined.

Align the address used by the LL/SC operations to double-word addresses (8 bytes) for best performance

Last Published: Jan 16, 2025

[Previous Topic
Data processing](https://docs.qualcomm.com/bundle/publicresource/80-N2040-60/topics/data-processing.md) [Next Topic
Conditional execution](https://docs.qualcomm.com/bundle/publicresource/80-N2040-60/topics/conditional-execution.md)