add dl814_k7_basic; update dl814_z7 ps project

dl814_k7_basic is the driver instance of board smq7k410t_b9361, along with basic clock, adc and dac configurations; include nulling algorithm into dl814_z7 project
This commit is contained in:
2023-03-29 17:34:49 +08:00
parent cd256a8cd6
commit e8a34c95e0
2060 changed files with 4678610 additions and 198681 deletions
@@ -4655,20 +4655,20 @@
"portIndex": 5,
"nets": [
{
"name": "rx_state__0",
"name": "rx_state__1",
"isBus": true,
"subnets": [
{
"name": "rx_state__0[3]"
"name": "rx_state__1[3]"
},
{
"name": "rx_state__0[2]"
"name": "rx_state__1[2]"
},
{
"name": "rx_state__0[1]"
"name": "rx_state__1[1]"
},
{
"name": "rx_state__0[0]",
"name": "rx_state__1[0]",
"parentNetId": 807
}
]
@@ -5879,6 +5879,937 @@
]
}
]
},
{
"type": "ILA_V3",
"name": "u_ila_null_dma_rx",
"spec": "labtools_ila_v6",
"ipName": "ila",
"core_location": {
"user_chain": 1,
"slave_index": 11,
"bscan_switch_index": 0
},
"uuid": "FE31857798F755E1AE742AF7A3613352",
"pins": [
{
"name": "probe0",
"id": 158,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 31,
"portIndex": 0,
"nets": [
{
"name": "c2c_rx_fifo_tdata__1",
"isBus": true,
"subnets": [
{
"name": "c2c_rx_fifo_tdata__1[31]"
},
{
"name": "c2c_rx_fifo_tdata__1[30]"
},
{
"name": "c2c_rx_fifo_tdata__1[29]"
},
{
"name": "c2c_rx_fifo_tdata__1[28]"
},
{
"name": "c2c_rx_fifo_tdata__1[27]"
},
{
"name": "c2c_rx_fifo_tdata__1[26]"
},
{
"name": "c2c_rx_fifo_tdata__1[25]"
},
{
"name": "c2c_rx_fifo_tdata__1[24]"
},
{
"name": "c2c_rx_fifo_tdata__1[23]"
},
{
"name": "c2c_rx_fifo_tdata__1[22]"
},
{
"name": "c2c_rx_fifo_tdata__1[21]"
},
{
"name": "c2c_rx_fifo_tdata__1[20]"
},
{
"name": "c2c_rx_fifo_tdata__1[19]"
},
{
"name": "c2c_rx_fifo_tdata__1[18]"
},
{
"name": "c2c_rx_fifo_tdata__1[17]"
},
{
"name": "c2c_rx_fifo_tdata__1[16]"
},
{
"name": "c2c_rx_fifo_tdata__1[15]"
},
{
"name": "c2c_rx_fifo_tdata__1[14]"
},
{
"name": "c2c_rx_fifo_tdata__1[13]"
},
{
"name": "c2c_rx_fifo_tdata__1[12]"
},
{
"name": "c2c_rx_fifo_tdata__1[11]"
},
{
"name": "c2c_rx_fifo_tdata__1[10]"
},
{
"name": "c2c_rx_fifo_tdata__1[9]"
},
{
"name": "c2c_rx_fifo_tdata__1[8]"
},
{
"name": "c2c_rx_fifo_tdata__1[7]"
},
{
"name": "c2c_rx_fifo_tdata__1[6]"
},
{
"name": "c2c_rx_fifo_tdata__1[5]"
},
{
"name": "c2c_rx_fifo_tdata__1[4]"
},
{
"name": "c2c_rx_fifo_tdata__1[3]"
},
{
"name": "c2c_rx_fifo_tdata__1[2]"
},
{
"name": "c2c_rx_fifo_tdata__1[1]"
},
{
"name": "c2c_rx_fifo_tdata__1[0]"
}
]
}
]
},
{
"name": "probe1",
"id": 159,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 1,
"nets": [
{
"name": "c2c_rx_fifo_tlast__1",
"isBus": false
}
]
},
{
"name": "probe2",
"id": 160,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 2,
"nets": [
{
"name": "c2c_rx_fifo_tready__1",
"isBus": false
}
]
},
{
"name": "probe3",
"id": 161,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 3,
"nets": [
{
"name": "c2c_rx_fifo_tvalid__1",
"isBus": false
}
]
},
{
"name": "probe4",
"id": 162,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 3,
"portIndex": 4,
"nets": [
{
"name": "rx_state__0",
"isBus": true,
"subnets": [
{
"name": "rx_state__0[3]"
},
{
"name": "rx_state__0[2]"
},
{
"name": "rx_state__0[1]"
},
{
"name": "rx_state__0[0]"
}
]
}
]
},
{
"name": "probe5",
"id": 163,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 3,
"portIndex": 5,
"nets": [
{
"name": "rx_state_next__0",
"isBus": true,
"subnets": [
{
"name": "rx_state_next__0[3]"
},
{
"name": "rx_state_next__0[2]"
},
{
"name": "rx_state_next__0[1]"
},
{
"name": "rx_state_next__0[0]"
}
]
}
]
},
{
"name": "probe6",
"id": 164,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 36,
"portIndex": 6,
"nets": [
{
"name": "rx_data_cnt__0",
"isBus": true,
"subnets": [
{
"name": "rx_data_cnt__0[36]"
},
{
"name": "rx_data_cnt__0[35]"
},
{
"name": "rx_data_cnt__0[34]"
},
{
"name": "rx_data_cnt__0[33]"
},
{
"name": "rx_data_cnt__0[32]"
},
{
"name": "rx_data_cnt__0[31]"
},
{
"name": "rx_data_cnt__0[30]"
},
{
"name": "rx_data_cnt__0[29]"
},
{
"name": "rx_data_cnt__0[28]"
},
{
"name": "rx_data_cnt__0[27]"
},
{
"name": "rx_data_cnt__0[26]"
},
{
"name": "rx_data_cnt__0[25]"
},
{
"name": "rx_data_cnt__0[24]"
},
{
"name": "rx_data_cnt__0[23]"
},
{
"name": "rx_data_cnt__0[22]"
},
{
"name": "rx_data_cnt__0[21]"
},
{
"name": "rx_data_cnt__0[20]"
},
{
"name": "rx_data_cnt__0[19]"
},
{
"name": "rx_data_cnt__0[18]"
},
{
"name": "rx_data_cnt__0[17]"
},
{
"name": "rx_data_cnt__0[16]"
},
{
"name": "rx_data_cnt__0[15]"
},
{
"name": "rx_data_cnt__0[14]"
},
{
"name": "rx_data_cnt__0[13]"
},
{
"name": "rx_data_cnt__0[12]"
},
{
"name": "rx_data_cnt__0[11]"
},
{
"name": "rx_data_cnt__0[10]"
},
{
"name": "rx_data_cnt__0[9]"
},
{
"name": "rx_data_cnt__0[8]"
},
{
"name": "rx_data_cnt__0[7]"
},
{
"name": "rx_data_cnt__0[6]"
},
{
"name": "rx_data_cnt__0[5]"
},
{
"name": "rx_data_cnt__0[4]"
},
{
"name": "rx_data_cnt__0[3]"
},
{
"name": "rx_data_cnt__0[2]"
},
{
"name": "rx_data_cnt__0[1]"
},
{
"name": "rx_data_cnt__0[0]"
}
]
}
]
},
{
"name": "probe7",
"id": 165,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 31,
"portIndex": 7,
"nets": [
{
"name": "rx_frame_length__0",
"isBus": true,
"subnets": [
{
"name": "rx_frame_length__0[31]"
},
{
"name": "rx_frame_length__0[30]"
},
{
"name": "rx_frame_length__0[29]"
},
{
"name": "rx_frame_length__0[28]"
},
{
"name": "rx_frame_length__0[27]"
},
{
"name": "rx_frame_length__0[26]"
},
{
"name": "rx_frame_length__0[25]"
},
{
"name": "rx_frame_length__0[24]"
},
{
"name": "rx_frame_length__0[23]"
},
{
"name": "rx_frame_length__0[22]"
},
{
"name": "rx_frame_length__0[21]"
},
{
"name": "rx_frame_length__0[20]"
},
{
"name": "rx_frame_length__0[19]"
},
{
"name": "rx_frame_length__0[18]"
},
{
"name": "rx_frame_length__0[17]"
},
{
"name": "rx_frame_length__0[16]"
},
{
"name": "rx_frame_length__0[15]"
},
{
"name": "rx_frame_length__0[14]"
},
{
"name": "rx_frame_length__0[13]"
},
{
"name": "rx_frame_length__0[12]"
},
{
"name": "rx_frame_length__0[11]"
},
{
"name": "rx_frame_length__0[10]"
},
{
"name": "rx_frame_length__0[9]"
},
{
"name": "rx_frame_length__0[8]"
},
{
"name": "rx_frame_length__0[7]"
},
{
"name": "rx_frame_length__0[6]"
},
{
"name": "rx_frame_length__0[5]"
},
{
"name": "rx_frame_length__0[4]"
},
{
"name": "rx_frame_length__0[3]"
},
{
"name": "rx_frame_length__0[2]"
},
{
"name": "rx_frame_length__0[1]"
},
{
"name": "rx_frame_length__0[0]"
}
]
}
]
},
{
"name": "probe8",
"id": 166,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 31,
"portIndex": 8,
"nets": [
{
"name": "rx_data_32__0",
"isBus": true,
"subnets": [
{
"name": "rx_data_32__0[31]"
},
{
"name": "rx_data_32__0[30]"
},
{
"name": "rx_data_32__0[29]"
},
{
"name": "rx_data_32__0[28]"
},
{
"name": "rx_data_32__0[27]"
},
{
"name": "rx_data_32__0[26]"
},
{
"name": "rx_data_32__0[25]"
},
{
"name": "rx_data_32__0[24]"
},
{
"name": "rx_data_32__0[23]"
},
{
"name": "rx_data_32__0[22]"
},
{
"name": "rx_data_32__0[21]"
},
{
"name": "rx_data_32__0[20]"
},
{
"name": "rx_data_32__0[19]"
},
{
"name": "rx_data_32__0[18]"
},
{
"name": "rx_data_32__0[17]"
},
{
"name": "rx_data_32__0[16]"
},
{
"name": "rx_data_32__0[15]"
},
{
"name": "rx_data_32__0[14]"
},
{
"name": "rx_data_32__0[13]"
},
{
"name": "rx_data_32__0[12]"
},
{
"name": "rx_data_32__0[11]"
},
{
"name": "rx_data_32__0[10]"
},
{
"name": "rx_data_32__0[9]"
},
{
"name": "rx_data_32__0[8]"
},
{
"name": "rx_data_32__0[7]"
},
{
"name": "rx_data_32__0[6]"
},
{
"name": "rx_data_32__0[5]"
},
{
"name": "rx_data_32__0[4]"
},
{
"name": "rx_data_32__0[3]"
},
{
"name": "rx_data_32__0[2]"
},
{
"name": "rx_data_32__0[1]"
},
{
"name": "rx_data_32__0[0]"
}
]
}
]
},
{
"name": "probe9",
"id": 167,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 9,
"nets": [
{
"name": "c2c_din__0",
"isBus": false
}
]
}
]
},
{
"type": "ILA_V3",
"name": "u_ila_null_dma_tx",
"spec": "labtools_ila_v6",
"ipName": "ila",
"core_location": {
"user_chain": 1,
"slave_index": 12,
"bscan_switch_index": 0
},
"uuid": "5124B92CF8375B9C816CC060E80644A5",
"pins": [
{
"name": "probe0",
"id": 168,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 31,
"portIndex": 0,
"nets": [
{
"name": "c2c_tx_fifo_tdata__1",
"isBus": true,
"subnets": [
{
"name": "c2c_tx_fifo_tdata__1[31]"
},
{
"name": "c2c_tx_fifo_tdata__1[30]"
},
{
"name": "c2c_tx_fifo_tdata__1[29]"
},
{
"name": "c2c_tx_fifo_tdata__1[28]"
},
{
"name": "c2c_tx_fifo_tdata__1[27]"
},
{
"name": "c2c_tx_fifo_tdata__1[26]"
},
{
"name": "c2c_tx_fifo_tdata__1[25]"
},
{
"name": "c2c_tx_fifo_tdata__1[24]"
},
{
"name": "c2c_tx_fifo_tdata__1[23]"
},
{
"name": "c2c_tx_fifo_tdata__1[22]"
},
{
"name": "c2c_tx_fifo_tdata__1[21]"
},
{
"name": "c2c_tx_fifo_tdata__1[20]"
},
{
"name": "c2c_tx_fifo_tdata__1[19]"
},
{
"name": "c2c_tx_fifo_tdata__1[18]"
},
{
"name": "c2c_tx_fifo_tdata__1[17]"
},
{
"name": "c2c_tx_fifo_tdata__1[16]"
},
{
"name": "c2c_tx_fifo_tdata__1[15]"
},
{
"name": "c2c_tx_fifo_tdata__1[14]"
},
{
"name": "c2c_tx_fifo_tdata__1[13]"
},
{
"name": "c2c_tx_fifo_tdata__1[12]"
},
{
"name": "c2c_tx_fifo_tdata__1[11]"
},
{
"name": "c2c_tx_fifo_tdata__1[10]"
},
{
"name": "c2c_tx_fifo_tdata__1[9]"
},
{
"name": "c2c_tx_fifo_tdata__1[8]"
},
{
"name": "c2c_tx_fifo_tdata__1[7]"
},
{
"name": "c2c_tx_fifo_tdata__1[6]"
},
{
"name": "c2c_tx_fifo_tdata__1[5]"
},
{
"name": "c2c_tx_fifo_tdata__1[4]"
},
{
"name": "c2c_tx_fifo_tdata__1[3]"
},
{
"name": "c2c_tx_fifo_tdata__1[2]"
},
{
"name": "c2c_tx_fifo_tdata__1[1]"
},
{
"name": "c2c_tx_fifo_tdata__1[0]"
}
]
}
]
},
{
"name": "probe1",
"id": 169,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 1,
"nets": [
{
"name": "c2c_tx_fifo_tlast__1",
"isBus": false
}
]
},
{
"name": "probe2",
"id": 170,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 2,
"nets": [
{
"name": "c2c_tx_fifo_tready__1",
"isBus": false
}
]
},
{
"name": "probe3",
"id": 171,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 3,
"nets": [
{
"name": "c2c_tx_fifo_tvalid__1",
"isBus": false
}
]
},
{
"name": "probe4",
"id": 172,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 4,
"nets": [
{
"name": "rst__0",
"isBus": false
}
]
},
{
"name": "probe5",
"id": 173,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 5,
"nets": [
{
"name": "c2c_dout__0",
"isBus": false
}
]
},
{
"name": "probe6",
"id": 174,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 31,
"portIndex": 6,
"nets": [
{
"name": "tx_data_32__0",
"isBus": true,
"subnets": [
{
"name": "tx_data_32__0[31]"
},
{
"name": "tx_data_32__0[30]"
},
{
"name": "tx_data_32__0[29]"
},
{
"name": "tx_data_32__0[28]"
},
{
"name": "tx_data_32__0[27]"
},
{
"name": "tx_data_32__0[26]"
},
{
"name": "tx_data_32__0[25]"
},
{
"name": "tx_data_32__0[24]"
},
{
"name": "tx_data_32__0[23]"
},
{
"name": "tx_data_32__0[22]"
},
{
"name": "tx_data_32__0[21]"
},
{
"name": "tx_data_32__0[20]"
},
{
"name": "tx_data_32__0[19]"
},
{
"name": "tx_data_32__0[18]"
},
{
"name": "tx_data_32__0[17]"
},
{
"name": "tx_data_32__0[16]"
},
{
"name": "tx_data_32__0[15]"
},
{
"name": "tx_data_32__0[14]"
},
{
"name": "tx_data_32__0[13]"
},
{
"name": "tx_data_32__0[12]"
},
{
"name": "tx_data_32__0[11]"
},
{
"name": "tx_data_32__0[10]"
},
{
"name": "tx_data_32__0[9]"
},
{
"name": "tx_data_32__0[8]"
},
{
"name": "tx_data_32__0[7]"
},
{
"name": "tx_data_32__0[6]"
},
{
"name": "tx_data_32__0[5]"
},
{
"name": "tx_data_32__0[4]"
},
{
"name": "tx_data_32__0[3]"
},
{
"name": "tx_data_32__0[2]"
},
{
"name": "tx_data_32__0[1]"
},
{
"name": "tx_data_32__0[0]"
}
]
}
]
}
]
}
],
"parent_nets": [
@@ -4655,20 +4655,20 @@
"portIndex": 5,
"nets": [
{
"name": "rx_state__0",
"name": "rx_state__1",
"isBus": true,
"subnets": [
{
"name": "rx_state__0[3]"
"name": "rx_state__1[3]"
},
{
"name": "rx_state__0[2]"
"name": "rx_state__1[2]"
},
{
"name": "rx_state__0[1]"
"name": "rx_state__1[1]"
},
{
"name": "rx_state__0[0]",
"name": "rx_state__1[0]",
"parentNetId": 807
}
]
@@ -5879,6 +5879,937 @@
]
}
]
},
{
"type": "ILA_V3",
"name": "u_ila_null_dma_rx",
"spec": "labtools_ila_v6",
"ipName": "ila",
"core_location": {
"user_chain": 1,
"slave_index": 11,
"bscan_switch_index": 0
},
"uuid": "FE31857798F755E1AE742AF7A3613352",
"pins": [
{
"name": "probe0",
"id": 158,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 31,
"portIndex": 0,
"nets": [
{
"name": "c2c_rx_fifo_tdata__1",
"isBus": true,
"subnets": [
{
"name": "c2c_rx_fifo_tdata__1[31]"
},
{
"name": "c2c_rx_fifo_tdata__1[30]"
},
{
"name": "c2c_rx_fifo_tdata__1[29]"
},
{
"name": "c2c_rx_fifo_tdata__1[28]"
},
{
"name": "c2c_rx_fifo_tdata__1[27]"
},
{
"name": "c2c_rx_fifo_tdata__1[26]"
},
{
"name": "c2c_rx_fifo_tdata__1[25]"
},
{
"name": "c2c_rx_fifo_tdata__1[24]"
},
{
"name": "c2c_rx_fifo_tdata__1[23]"
},
{
"name": "c2c_rx_fifo_tdata__1[22]"
},
{
"name": "c2c_rx_fifo_tdata__1[21]"
},
{
"name": "c2c_rx_fifo_tdata__1[20]"
},
{
"name": "c2c_rx_fifo_tdata__1[19]"
},
{
"name": "c2c_rx_fifo_tdata__1[18]"
},
{
"name": "c2c_rx_fifo_tdata__1[17]"
},
{
"name": "c2c_rx_fifo_tdata__1[16]"
},
{
"name": "c2c_rx_fifo_tdata__1[15]"
},
{
"name": "c2c_rx_fifo_tdata__1[14]"
},
{
"name": "c2c_rx_fifo_tdata__1[13]"
},
{
"name": "c2c_rx_fifo_tdata__1[12]"
},
{
"name": "c2c_rx_fifo_tdata__1[11]"
},
{
"name": "c2c_rx_fifo_tdata__1[10]"
},
{
"name": "c2c_rx_fifo_tdata__1[9]"
},
{
"name": "c2c_rx_fifo_tdata__1[8]"
},
{
"name": "c2c_rx_fifo_tdata__1[7]"
},
{
"name": "c2c_rx_fifo_tdata__1[6]"
},
{
"name": "c2c_rx_fifo_tdata__1[5]"
},
{
"name": "c2c_rx_fifo_tdata__1[4]"
},
{
"name": "c2c_rx_fifo_tdata__1[3]"
},
{
"name": "c2c_rx_fifo_tdata__1[2]"
},
{
"name": "c2c_rx_fifo_tdata__1[1]"
},
{
"name": "c2c_rx_fifo_tdata__1[0]"
}
]
}
]
},
{
"name": "probe1",
"id": 159,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 1,
"nets": [
{
"name": "c2c_rx_fifo_tlast__1",
"isBus": false
}
]
},
{
"name": "probe2",
"id": 160,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 2,
"nets": [
{
"name": "c2c_rx_fifo_tready__1",
"isBus": false
}
]
},
{
"name": "probe3",
"id": 161,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 3,
"nets": [
{
"name": "c2c_rx_fifo_tvalid__1",
"isBus": false
}
]
},
{
"name": "probe4",
"id": 162,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 3,
"portIndex": 4,
"nets": [
{
"name": "rx_state__0",
"isBus": true,
"subnets": [
{
"name": "rx_state__0[3]"
},
{
"name": "rx_state__0[2]"
},
{
"name": "rx_state__0[1]"
},
{
"name": "rx_state__0[0]"
}
]
}
]
},
{
"name": "probe5",
"id": 163,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 3,
"portIndex": 5,
"nets": [
{
"name": "rx_state_next__0",
"isBus": true,
"subnets": [
{
"name": "rx_state_next__0[3]"
},
{
"name": "rx_state_next__0[2]"
},
{
"name": "rx_state_next__0[1]"
},
{
"name": "rx_state_next__0[0]"
}
]
}
]
},
{
"name": "probe6",
"id": 164,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 36,
"portIndex": 6,
"nets": [
{
"name": "rx_data_cnt__0",
"isBus": true,
"subnets": [
{
"name": "rx_data_cnt__0[36]"
},
{
"name": "rx_data_cnt__0[35]"
},
{
"name": "rx_data_cnt__0[34]"
},
{
"name": "rx_data_cnt__0[33]"
},
{
"name": "rx_data_cnt__0[32]"
},
{
"name": "rx_data_cnt__0[31]"
},
{
"name": "rx_data_cnt__0[30]"
},
{
"name": "rx_data_cnt__0[29]"
},
{
"name": "rx_data_cnt__0[28]"
},
{
"name": "rx_data_cnt__0[27]"
},
{
"name": "rx_data_cnt__0[26]"
},
{
"name": "rx_data_cnt__0[25]"
},
{
"name": "rx_data_cnt__0[24]"
},
{
"name": "rx_data_cnt__0[23]"
},
{
"name": "rx_data_cnt__0[22]"
},
{
"name": "rx_data_cnt__0[21]"
},
{
"name": "rx_data_cnt__0[20]"
},
{
"name": "rx_data_cnt__0[19]"
},
{
"name": "rx_data_cnt__0[18]"
},
{
"name": "rx_data_cnt__0[17]"
},
{
"name": "rx_data_cnt__0[16]"
},
{
"name": "rx_data_cnt__0[15]"
},
{
"name": "rx_data_cnt__0[14]"
},
{
"name": "rx_data_cnt__0[13]"
},
{
"name": "rx_data_cnt__0[12]"
},
{
"name": "rx_data_cnt__0[11]"
},
{
"name": "rx_data_cnt__0[10]"
},
{
"name": "rx_data_cnt__0[9]"
},
{
"name": "rx_data_cnt__0[8]"
},
{
"name": "rx_data_cnt__0[7]"
},
{
"name": "rx_data_cnt__0[6]"
},
{
"name": "rx_data_cnt__0[5]"
},
{
"name": "rx_data_cnt__0[4]"
},
{
"name": "rx_data_cnt__0[3]"
},
{
"name": "rx_data_cnt__0[2]"
},
{
"name": "rx_data_cnt__0[1]"
},
{
"name": "rx_data_cnt__0[0]"
}
]
}
]
},
{
"name": "probe7",
"id": 165,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 31,
"portIndex": 7,
"nets": [
{
"name": "rx_frame_length__0",
"isBus": true,
"subnets": [
{
"name": "rx_frame_length__0[31]"
},
{
"name": "rx_frame_length__0[30]"
},
{
"name": "rx_frame_length__0[29]"
},
{
"name": "rx_frame_length__0[28]"
},
{
"name": "rx_frame_length__0[27]"
},
{
"name": "rx_frame_length__0[26]"
},
{
"name": "rx_frame_length__0[25]"
},
{
"name": "rx_frame_length__0[24]"
},
{
"name": "rx_frame_length__0[23]"
},
{
"name": "rx_frame_length__0[22]"
},
{
"name": "rx_frame_length__0[21]"
},
{
"name": "rx_frame_length__0[20]"
},
{
"name": "rx_frame_length__0[19]"
},
{
"name": "rx_frame_length__0[18]"
},
{
"name": "rx_frame_length__0[17]"
},
{
"name": "rx_frame_length__0[16]"
},
{
"name": "rx_frame_length__0[15]"
},
{
"name": "rx_frame_length__0[14]"
},
{
"name": "rx_frame_length__0[13]"
},
{
"name": "rx_frame_length__0[12]"
},
{
"name": "rx_frame_length__0[11]"
},
{
"name": "rx_frame_length__0[10]"
},
{
"name": "rx_frame_length__0[9]"
},
{
"name": "rx_frame_length__0[8]"
},
{
"name": "rx_frame_length__0[7]"
},
{
"name": "rx_frame_length__0[6]"
},
{
"name": "rx_frame_length__0[5]"
},
{
"name": "rx_frame_length__0[4]"
},
{
"name": "rx_frame_length__0[3]"
},
{
"name": "rx_frame_length__0[2]"
},
{
"name": "rx_frame_length__0[1]"
},
{
"name": "rx_frame_length__0[0]"
}
]
}
]
},
{
"name": "probe8",
"id": 166,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 31,
"portIndex": 8,
"nets": [
{
"name": "rx_data_32__0",
"isBus": true,
"subnets": [
{
"name": "rx_data_32__0[31]"
},
{
"name": "rx_data_32__0[30]"
},
{
"name": "rx_data_32__0[29]"
},
{
"name": "rx_data_32__0[28]"
},
{
"name": "rx_data_32__0[27]"
},
{
"name": "rx_data_32__0[26]"
},
{
"name": "rx_data_32__0[25]"
},
{
"name": "rx_data_32__0[24]"
},
{
"name": "rx_data_32__0[23]"
},
{
"name": "rx_data_32__0[22]"
},
{
"name": "rx_data_32__0[21]"
},
{
"name": "rx_data_32__0[20]"
},
{
"name": "rx_data_32__0[19]"
},
{
"name": "rx_data_32__0[18]"
},
{
"name": "rx_data_32__0[17]"
},
{
"name": "rx_data_32__0[16]"
},
{
"name": "rx_data_32__0[15]"
},
{
"name": "rx_data_32__0[14]"
},
{
"name": "rx_data_32__0[13]"
},
{
"name": "rx_data_32__0[12]"
},
{
"name": "rx_data_32__0[11]"
},
{
"name": "rx_data_32__0[10]"
},
{
"name": "rx_data_32__0[9]"
},
{
"name": "rx_data_32__0[8]"
},
{
"name": "rx_data_32__0[7]"
},
{
"name": "rx_data_32__0[6]"
},
{
"name": "rx_data_32__0[5]"
},
{
"name": "rx_data_32__0[4]"
},
{
"name": "rx_data_32__0[3]"
},
{
"name": "rx_data_32__0[2]"
},
{
"name": "rx_data_32__0[1]"
},
{
"name": "rx_data_32__0[0]"
}
]
}
]
},
{
"name": "probe9",
"id": 167,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 9,
"nets": [
{
"name": "c2c_din__0",
"isBus": false
}
]
}
]
},
{
"type": "ILA_V3",
"name": "u_ila_null_dma_tx",
"spec": "labtools_ila_v6",
"ipName": "ila",
"core_location": {
"user_chain": 1,
"slave_index": 12,
"bscan_switch_index": 0
},
"uuid": "5124B92CF8375B9C816CC060E80644A5",
"pins": [
{
"name": "probe0",
"id": 168,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 31,
"portIndex": 0,
"nets": [
{
"name": "c2c_tx_fifo_tdata__1",
"isBus": true,
"subnets": [
{
"name": "c2c_tx_fifo_tdata__1[31]"
},
{
"name": "c2c_tx_fifo_tdata__1[30]"
},
{
"name": "c2c_tx_fifo_tdata__1[29]"
},
{
"name": "c2c_tx_fifo_tdata__1[28]"
},
{
"name": "c2c_tx_fifo_tdata__1[27]"
},
{
"name": "c2c_tx_fifo_tdata__1[26]"
},
{
"name": "c2c_tx_fifo_tdata__1[25]"
},
{
"name": "c2c_tx_fifo_tdata__1[24]"
},
{
"name": "c2c_tx_fifo_tdata__1[23]"
},
{
"name": "c2c_tx_fifo_tdata__1[22]"
},
{
"name": "c2c_tx_fifo_tdata__1[21]"
},
{
"name": "c2c_tx_fifo_tdata__1[20]"
},
{
"name": "c2c_tx_fifo_tdata__1[19]"
},
{
"name": "c2c_tx_fifo_tdata__1[18]"
},
{
"name": "c2c_tx_fifo_tdata__1[17]"
},
{
"name": "c2c_tx_fifo_tdata__1[16]"
},
{
"name": "c2c_tx_fifo_tdata__1[15]"
},
{
"name": "c2c_tx_fifo_tdata__1[14]"
},
{
"name": "c2c_tx_fifo_tdata__1[13]"
},
{
"name": "c2c_tx_fifo_tdata__1[12]"
},
{
"name": "c2c_tx_fifo_tdata__1[11]"
},
{
"name": "c2c_tx_fifo_tdata__1[10]"
},
{
"name": "c2c_tx_fifo_tdata__1[9]"
},
{
"name": "c2c_tx_fifo_tdata__1[8]"
},
{
"name": "c2c_tx_fifo_tdata__1[7]"
},
{
"name": "c2c_tx_fifo_tdata__1[6]"
},
{
"name": "c2c_tx_fifo_tdata__1[5]"
},
{
"name": "c2c_tx_fifo_tdata__1[4]"
},
{
"name": "c2c_tx_fifo_tdata__1[3]"
},
{
"name": "c2c_tx_fifo_tdata__1[2]"
},
{
"name": "c2c_tx_fifo_tdata__1[1]"
},
{
"name": "c2c_tx_fifo_tdata__1[0]"
}
]
}
]
},
{
"name": "probe1",
"id": 169,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 1,
"nets": [
{
"name": "c2c_tx_fifo_tlast__1",
"isBus": false
}
]
},
{
"name": "probe2",
"id": 170,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 2,
"nets": [
{
"name": "c2c_tx_fifo_tready__1",
"isBus": false
}
]
},
{
"name": "probe3",
"id": 171,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 3,
"nets": [
{
"name": "c2c_tx_fifo_tvalid__1",
"isBus": false
}
]
},
{
"name": "probe4",
"id": 172,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 4,
"nets": [
{
"name": "rst__0",
"isBus": false
}
]
},
{
"name": "probe5",
"id": 173,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": false,
"leftIndex": 0,
"rightIndex": 0,
"portIndex": 5,
"nets": [
{
"name": "c2c_dout__0",
"isBus": false
}
]
},
{
"name": "probe6",
"id": 174,
"type": "DATA_TRIGGER",
"direction": "IN",
"isVector": true,
"leftIndex": 0,
"rightIndex": 31,
"portIndex": 6,
"nets": [
{
"name": "tx_data_32__0",
"isBus": true,
"subnets": [
{
"name": "tx_data_32__0[31]"
},
{
"name": "tx_data_32__0[30]"
},
{
"name": "tx_data_32__0[29]"
},
{
"name": "tx_data_32__0[28]"
},
{
"name": "tx_data_32__0[27]"
},
{
"name": "tx_data_32__0[26]"
},
{
"name": "tx_data_32__0[25]"
},
{
"name": "tx_data_32__0[24]"
},
{
"name": "tx_data_32__0[23]"
},
{
"name": "tx_data_32__0[22]"
},
{
"name": "tx_data_32__0[21]"
},
{
"name": "tx_data_32__0[20]"
},
{
"name": "tx_data_32__0[19]"
},
{
"name": "tx_data_32__0[18]"
},
{
"name": "tx_data_32__0[17]"
},
{
"name": "tx_data_32__0[16]"
},
{
"name": "tx_data_32__0[15]"
},
{
"name": "tx_data_32__0[14]"
},
{
"name": "tx_data_32__0[13]"
},
{
"name": "tx_data_32__0[12]"
},
{
"name": "tx_data_32__0[11]"
},
{
"name": "tx_data_32__0[10]"
},
{
"name": "tx_data_32__0[9]"
},
{
"name": "tx_data_32__0[8]"
},
{
"name": "tx_data_32__0[7]"
},
{
"name": "tx_data_32__0[6]"
},
{
"name": "tx_data_32__0[5]"
},
{
"name": "tx_data_32__0[4]"
},
{
"name": "tx_data_32__0[3]"
},
{
"name": "tx_data_32__0[2]"
},
{
"name": "tx_data_32__0[1]"
},
{
"name": "tx_data_32__0[0]"
}
]
}
]
}
]
}
],
"parent_nets": [
@@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="xilinx.gnu.armv7.exe.debug.884384275">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.armv7.exe.debug.884384275" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="com.xilinx.sdk.managedbuilder.XELF.arm.a53.x32" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="xilinx.gnu.armv7.exe.debug.884384275" name="Debug" parent="xilinx.gnu.armv7.exe.debug" prebuildStep="a9-linaro-pre-build-step">
<folderInfo id="xilinx.gnu.armv7.exe.debug.884384275." name="/" resourcePath="">
<toolChain id="xilinx.gnu.armv7.exe.debug.toolchain.354279415" name="Xilinx ARM v7 GNU Toolchain" superClass="xilinx.gnu.armv7.exe.debug.toolchain">
<targetPlatform binaryParser="com.xilinx.sdk.managedbuilder.XELF.arm.a53.x32" id="xilinx.armv7.target.gnu.base.debug.974325489" isAbstract="false" name="Debug Platform" superClass="xilinx.armv7.target.gnu.base.debug"/>
<builder buildPath="${workspace_loc:/dl814_null}/Debug" enableAutoBuild="true" id="xilinx.gnu.armv7.toolchain.builder.debug.426852875" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="GNU make" superClass="xilinx.gnu.armv7.toolchain.builder.debug"/>
<tool id="xilinx.gnu.armv7.c.toolchain.assembler.debug.714428348" name="ARM v7 gcc assembler" superClass="xilinx.gnu.armv7.c.toolchain.assembler.debug">
<inputType id="xilinx.gnu.assembler.input.1065623993" superClass="xilinx.gnu.assembler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.c.toolchain.compiler.debug.644396600" name="ARM v7 gcc compiler" superClass="xilinx.gnu.armv7.c.toolchain.compiler.debug">
<option defaultValue="gnu.c.optimization.level.none" id="xilinx.gnu.compiler.option.optimization.level.561767289" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.631714575" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.1280535103" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath"/>
<option id="xilinx.gnu.compiler.misc.other.2036573556" name="Other flags" superClass="xilinx.gnu.compiler.misc.other" value="-c -fmessage-length=0 -MT&quot;$@&quot; -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard" valueType="string"/>
<option id="xilinx.gnu.compiler.dircategory.includes.1518247544" name="Include Paths" superClass="xilinx.gnu.compiler.dircategory.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../dl814_null_bsp/ps7_cortexa9_1/include"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/dl814_null/src/CMSIS-Core_A/Include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/dl814_null/src/CMSIS-DSP/Include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/dl814_null/src/CMSIS-DSP/PrivateInclude}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/dl814_null/src/CMSIS-DSP/ComputeLibrary/Include}&quot;"/>
</option>
<inputType id="xilinx.gnu.armv7.c.compiler.input.172105719" name="C source files" superClass="xilinx.gnu.armv7.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.compiler.debug.2059215157" name="ARM v7 g++ compiler" superClass="xilinx.gnu.armv7.cxx.toolchain.compiler.debug">
<option defaultValue="gnu.c.optimization.level.none" id="xilinx.gnu.compiler.option.optimization.level.1964978247" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1930590292" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.1768449991" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../dl814_null_bsp/ps7_cortexa9_1/include"/>
</option>
</tool>
<tool id="xilinx.gnu.armv7.toolchain.archiver.956344439" name="ARM v7 archiver" superClass="xilinx.gnu.armv7.toolchain.archiver"/>
<tool id="xilinx.gnu.armv7.c.toolchain.linker.debug.378394542" name="ARM v7 gcc linker" superClass="xilinx.gnu.armv7.c.toolchain.linker.debug">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1194961550" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="../../dl814_null_bsp/ps7_cortexa9_1/lib"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1615838315" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.1569042906" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<option id="xilinx.gnu.c.link.option.ldflags.1503266483" name="Linker Flags" superClass="xilinx.gnu.c.link.option.ldflags" value=" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -specs=Xilinx.spec" valueType="string"/>
<option id="xilinx.gnu.c.link.option.libs.1788355790" superClass="xilinx.gnu.c.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="m"/>
</option>
<inputType id="xilinx.gnu.linker.input.1662439396" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.1508370451" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.linker.debug.1326830384" name="ARM v7 g++ linker" superClass="xilinx.gnu.armv7.cxx.toolchain.linker.debug">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.168284542" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="../../dl814_null_bsp/ps7_cortexa9_1/lib"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.853739130" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.382021906" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
</tool>
<tool id="xilinx.gnu.armv7.size.debug.1041302152" name="ARM v7 Print Size" superClass="xilinx.gnu.armv7.size.debug"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="xilinx.gnu.armv7.exe.release.256497372">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.armv7.exe.release.256497372" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="com.xilinx.sdk.managedbuilder.XELF.arm.a53.x32" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="xilinx.gnu.armv7.exe.release.256497372" name="Release" parent="xilinx.gnu.armv7.exe.release" prebuildStep="a9-linaro-pre-build-step">
<folderInfo id="xilinx.gnu.armv7.exe.release.256497372." name="/" resourcePath="">
<toolChain id="xilinx.gnu.armv7.exe.release.toolchain.1956987533" name="Xilinx ARM v7 GNU Toolchain" superClass="xilinx.gnu.armv7.exe.release.toolchain">
<targetPlatform binaryParser="com.xilinx.sdk.managedbuilder.XELF.arm.a53.x32" id="xilinx.armv7.target.gnu.base.release.712404945" isAbstract="false" name="Release Platform" superClass="xilinx.armv7.target.gnu.base.release"/>
<builder buildPath="${workspace_loc:/dl814_null}/Release" enableAutoBuild="true" id="xilinx.gnu.armv7.toolchain.builder.release.2089099250" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="GNU make" superClass="xilinx.gnu.armv7.toolchain.builder.release"/>
<tool id="xilinx.gnu.armv7.c.toolchain.assembler.release.1115480388" name="ARM v7 gcc assembler" superClass="xilinx.gnu.armv7.c.toolchain.assembler.release">
<inputType id="xilinx.gnu.assembler.input.1100187045" superClass="xilinx.gnu.assembler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.c.toolchain.compiler.release.256894595" name="ARM v7 gcc compiler" superClass="xilinx.gnu.armv7.c.toolchain.compiler.release">
<option defaultValue="gnu.c.optimization.level.more" id="xilinx.gnu.compiler.option.optimization.level.1364047350" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1050297650" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.1046634436" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../dl814_null_bsp/ps7_cortexa9_1/include"/>
</option>
<option id="xilinx.gnu.compiler.misc.other.1979271087" name="Other flags" superClass="xilinx.gnu.compiler.misc.other" value="-c -fmessage-length=0 -MT&quot;$@&quot; -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard" valueType="string"/>
<inputType id="xilinx.gnu.armv7.c.compiler.input.1425542117" name="C source files" superClass="xilinx.gnu.armv7.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.compiler.release.482619750" name="ARM v7 g++ compiler" superClass="xilinx.gnu.armv7.cxx.toolchain.compiler.release">
<option defaultValue="gnu.c.optimization.level.more" id="xilinx.gnu.compiler.option.optimization.level.963927566" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.802640246" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.85091346" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../dl814_null_bsp/ps7_cortexa9_1/include"/>
</option>
</tool>
<tool id="xilinx.gnu.armv7.toolchain.archiver.551830751" name="ARM v7 archiver" superClass="xilinx.gnu.armv7.toolchain.archiver"/>
<tool id="xilinx.gnu.armv7.c.toolchain.linker.release.935311061" name="ARM v7 gcc linker" superClass="xilinx.gnu.armv7.c.toolchain.linker.release">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.2105585329" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="../../dl814_null_bsp/ps7_cortexa9_1/lib"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.2037286970" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.849972329" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<option id="xilinx.gnu.c.link.option.ldflags.1844327528" name="Linker Flags" superClass="xilinx.gnu.c.link.option.ldflags" value=" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -specs=Xilinx.spec" valueType="string"/>
<inputType id="xilinx.gnu.linker.input.817626122" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.285087693" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.armv7.cxx.toolchain.linker.release.929076790" name="ARM v7 g++ linker" superClass="xilinx.gnu.armv7.cxx.toolchain.linker.release">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.443925636" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="../../dl814_null_bsp/ps7_cortexa9_1/lib"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.2107829834" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.258609049" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
</tool>
<tool id="xilinx.gnu.armv7.size.release.276919502" name="ARM v7 Print Size" superClass="xilinx.gnu.armv7.size.release"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="dl814_null.xilinx.gnu.armv7.exe.1185579202" name="Xilinx ARM v7 Executable" projectType="xilinx.gnu.armv7.exe"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="xilinx.gnu.armv7.exe.debug.884384275;xilinx.gnu.armv7.exe.debug.884384275.;xilinx.gnu.armv7.c.toolchain.compiler.debug.644396600;xilinx.gnu.armv7.c.compiler.input.172105719">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53X32GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.armv7.exe.debug.884384275;xilinx.gnu.armv7.exe.debug.884384275.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53X32GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.armv7.exe.release.256497372;xilinx.gnu.armv7.exe.release.256497372.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53X32GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.armv7.exe.release.256497372;xilinx.gnu.armv7.exe.release.256497372.;xilinx.gnu.armv7.c.toolchain.compiler.release.256894595;xilinx.gnu.armv7.c.compiler.input.1425542117">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMA53X32GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/dl814_null"/>
</configuration>
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/dl814_null"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cproject>
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>dl814_null</name>
<comment>Created by SDK v2019.1. dl814_null_bsp - ps7_cortexa9_1</comment>
<projects>
<project>dl814_null_bsp</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,38 @@
eclipse.preferences.version=1
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.nocommentinside=-Error
org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.nolinecomment=-Error
org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
@@ -0,0 +1,563 @@
/**************************************************************************//**
* @file cmsis_armcc.h
* @brief CMSIS compiler specific macros, functions, instructions
* @version V1.0.5
* @date 05. May 2021
******************************************************************************/
/*
* Copyright (c) 2009-2021 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CMSIS_ARMCC_H
#define __CMSIS_ARMCC_H
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use Arm Compiler Toolchain V4.0.677 or later!"
#endif
/* CMSIS compiler control architecture macros */
#if (defined (__TARGET_ARCH_7_A ) && (__TARGET_ARCH_7_A == 1))
#define __ARM_ARCH_7A__ 1
#endif
/* CMSIS compiler specific defines */
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE __inline
#endif
#ifndef __FORCEINLINE
#define __FORCEINLINE __forceinline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static __inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE static __forceinline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __declspec(noreturn)
#endif
#ifndef CMSIS_DEPRECATED
#define CMSIS_DEPRECATED __attribute__((deprecated))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT __packed struct
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __COMPILER_BARRIER
#define __COMPILER_BARRIER() __memory_changed()
#endif
/* ########################## Core Instruction Access ######################### */
/**
\brief No Operation
*/
#define __NOP __nop
/**
\brief Wait For Interrupt
*/
#define __WFI __wfi
/**
\brief Wait For Event
*/
#define __WFE __wfe
/**
\brief Send Event
*/
#define __SEV __sev
/**
\brief Instruction Synchronization Barrier
*/
#define __ISB() __isb(0xF)
/**
\brief Data Synchronization Barrier
*/
#define __DSB() __dsb(0xF)
/**
\brief Data Memory Barrier
*/
#define __DMB() __dmb(0xF)
/**
\brief Reverse byte order (32 bit)
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
{
revsh r0, r0
bx lr
}
#endif
/**
\brief Rotate Right in unsigned value (32 bit)
\param [in] op1 Value to rotate
\param [in] op2 Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/**
\brief Breakpoint
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
/**
\brief Reverse bit order of value
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/**
\brief Count leading zeros
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#else
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#else
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#else
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXB(value, ptr) __strex(value, ptr)
#else
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXH(value, ptr) __strex(value, ptr)
#else
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXW(value, ptr) __strex(value, ptr)
#else
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/* ########################### Core Function Access ########################### */
/**
\brief Enable IRQ Interrupts
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
/* intrinsic void __enable_irq(); */
/**
\brief Disable IRQ Interrupts
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
/* intrinsic void __disable_irq(void); */
/**
\brief Enable FIQ
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/**
\brief Disable FIQ
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/**
\brief Get FPSCR (Floating Point Status/Control)
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0U);
#endif
}
/**
\brief Set FPSCR (Floating Point Status/Control)
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#else
(void)fpscr;
#endif
}
/** \brief Get CPSR (Current Program Status Register)
\return CPSR Register value
*/
__STATIC_INLINE uint32_t __get_CPSR(void)
{
register uint32_t __regCPSR __ASM("cpsr");
return(__regCPSR);
}
/** \brief Set CPSR (Current Program Status Register)
\param [in] cpsr CPSR value to set
*/
__STATIC_INLINE void __set_CPSR(uint32_t cpsr)
{
register uint32_t __regCPSR __ASM("cpsr");
__regCPSR = cpsr;
}
/** \brief Get Mode
\return Processor Mode
*/
__STATIC_INLINE uint32_t __get_mode(void)
{
return (__get_CPSR() & 0x1FU);
}
/** \brief Set Mode
\param [in] mode Mode value to set
*/
__STATIC_INLINE __ASM void __set_mode(uint32_t mode)
{
MOV r1, lr
MSR CPSR_C, r0
BX r1
}
/** \brief Get Stack Pointer
\return Stack Pointer
*/
__STATIC_INLINE __ASM uint32_t __get_SP(void)
{
MOV r0, sp
BX lr
}
/** \brief Set Stack Pointer
\param [in] stack Stack Pointer value to set
*/
__STATIC_INLINE __ASM void __set_SP(uint32_t stack)
{
MOV sp, r0
BX lr
}
/** \brief Get USR/SYS Stack Pointer
\return USR/SYSStack Pointer
*/
__STATIC_INLINE __ASM uint32_t __get_SP_usr(void)
{
ARM
PRESERVE8
MRS R1, CPSR
CPS #0x1F ;no effect in USR mode
MOV R0, SP
MSR CPSR_c, R1 ;no effect in USR mode
ISB
BX LR
}
/** \brief Set USR/SYS Stack Pointer
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
*/
__STATIC_INLINE __ASM void __set_SP_usr(uint32_t topOfProcStack)
{
ARM
PRESERVE8
MRS R1, CPSR
CPS #0x1F ;no effect in USR mode
MOV SP, R0
MSR CPSR_c, R1 ;no effect in USR mode
ISB
BX LR
}
/** \brief Get FPEXC (Floating Point Exception Control Register)
\return Floating Point Exception Control Register value
*/
__STATIC_INLINE uint32_t __get_FPEXC(void)
{
#if (__FPU_PRESENT == 1)
register uint32_t __regfpexc __ASM("fpexc");
return(__regfpexc);
#else
return(0);
#endif
}
/** \brief Set FPEXC (Floating Point Exception Control Register)
\param [in] fpexc Floating Point Exception Control value to set
*/
__STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
{
#if (__FPU_PRESENT == 1)
register uint32_t __regfpexc __ASM("fpexc");
__regfpexc = (fpexc);
#endif
}
/*
* Include common core functions to access Coprocessor 15 registers
*/
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); (Rt) = tmp; } while(0)
#define __set_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); tmp = (Rt); } while(0)
#define __get_CP64(cp, op1, Rt, CRm) \
do { \
uint32_t ltmp, htmp; \
__ASM volatile("MRRC p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \
(Rt) = ((((uint64_t)htmp) << 32U) | ((uint64_t)ltmp)); \
} while(0)
#define __set_CP64(cp, op1, Rt, CRm) \
do { \
const uint64_t tmp = (Rt); \
const uint32_t ltmp = (uint32_t)(tmp); \
const uint32_t htmp = (uint32_t)(tmp >> 32U); \
__ASM volatile("MCRR p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \
} while(0)
#include "cmsis_cp15.h"
/** \brief Enable Floating Point Unit
Critical section, called from undef handler, so systick is disabled
*/
__STATIC_INLINE __ASM void __FPU_Enable(void)
{
ARM
//Permit access to VFP/NEON, registers by modifying CPACR
MRC p15,0,R1,c1,c0,2
ORR R1,R1,#0x00F00000
MCR p15,0,R1,c1,c0,2
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
ISB
//Enable VFP/NEON
VMRS R1,FPEXC
ORR R1,R1,#0x40000000
VMSR FPEXC,R1
//Initialise VFP/NEON registers to 0
MOV R2,#0
//Initialise D16 registers to 0
VMOV D0, R2,R2
VMOV D1, R2,R2
VMOV D2, R2,R2
VMOV D3, R2,R2
VMOV D4, R2,R2
VMOV D5, R2,R2
VMOV D6, R2,R2
VMOV D7, R2,R2
VMOV D8, R2,R2
VMOV D9, R2,R2
VMOV D10,R2,R2
VMOV D11,R2,R2
VMOV D12,R2,R2
VMOV D13,R2,R2
VMOV D14,R2,R2
VMOV D15,R2,R2
IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32
//Initialise D32 registers to 0
VMOV D16,R2,R2
VMOV D17,R2,R2
VMOV D18,R2,R2
VMOV D19,R2,R2
VMOV D20,R2,R2
VMOV D21,R2,R2
VMOV D22,R2,R2
VMOV D23,R2,R2
VMOV D24,R2,R2
VMOV D25,R2,R2
VMOV D26,R2,R2
VMOV D27,R2,R2
VMOV D28,R2,R2
VMOV D29,R2,R2
VMOV D30,R2,R2
VMOV D31,R2,R2
ENDIF
//Initialise FPSCR to a known state
VMRS R1,FPSCR
LDR R2,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
AND R1,R1,R2
VMSR FPSCR,R1
BX LR
}
#endif /* __CMSIS_ARMCC_H */
@@ -0,0 +1,614 @@
/**************************************************************************//**
* @file cmsis_armclang.h
* @brief CMSIS compiler specific macros, functions, instructions
* @version V1.2.1
* @date 05. May 2021
******************************************************************************/
/*
* Copyright (c) 2009-2021 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CMSIS_ARMCLANG_H
#define __CMSIS_ARMCLANG_H
#pragma clang system_header /* treat file as system include file */
/* CMSIS compiler specific defines */
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE __inline
#endif
#ifndef __FORCEINLINE
#define __FORCEINLINE __attribute__((always_inline))
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static __inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((__noreturn__))
#endif
#ifndef CMSIS_DEPRECATED
#define CMSIS_DEPRECATED __attribute__((deprecated))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed, aligned(1)))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpacked"
/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#pragma clang diagnostic pop
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpacked"
/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#pragma clang diagnostic pop
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpacked"
/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#pragma clang diagnostic pop
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpacked"
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#pragma clang diagnostic pop
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __COMPILER_BARRIER
#define __COMPILER_BARRIER() __ASM volatile("":::"memory")
#endif
/* ########################## Core Instruction Access ######################### */
/**
\brief No Operation
*/
#define __NOP __builtin_arm_nop
/**
\brief Wait For Interrupt
*/
#define __WFI __builtin_arm_wfi
/**
\brief Wait For Event
*/
#define __WFE __builtin_arm_wfe
/**
\brief Send Event
*/
#define __SEV __builtin_arm_sev
/**
\brief Instruction Synchronization Barrier
*/
#define __ISB() __builtin_arm_isb(0xF)
/**
\brief Data Synchronization Barrier
*/
#define __DSB() __builtin_arm_dsb(0xF)
/**
\brief Data Memory Barrier
*/
#define __DMB() __builtin_arm_dmb(0xF)
/**
\brief Reverse byte order (32 bit)
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV(value) __builtin_bswap32(value)
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV16(value) __ROR(__REV(value), 16)
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REVSH(value) (int16_t)__builtin_bswap16(value)
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] op1 Value to rotate
\param [in] op2 Number of Bits to rotate
\return Rotated value
*/
__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
op2 %= 32U;
if (op2 == 0U)
{
return op1;
}
return (op1 >> op2) | (op1 << (32U - op2));
}
/**
\brief Breakpoint
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __ASM volatile ("bkpt "#value)
/**
\brief Reverse bit order of value
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __builtin_arm_rbit
/**
\brief Count leading zeros
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value)
{
/* Even though __builtin_clz produces a CLZ instruction on ARM, formally
__builtin_clz(0) is undefined behaviour, so handle this case specially.
This guarantees ARM-compatible results if happening to compile on a non-ARM
target, and ensures the compiler doesn't decide to activate any
optimisations using the logic "value was passed to __builtin_clz, so it
is non-zero".
ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a
single CLZ instruction.
*/
if (value == 0U)
{
return 32U;
}
return __builtin_clz(value);
}
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB (uint8_t)__builtin_arm_ldrex
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH (uint16_t)__builtin_arm_ldrex
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW (uint32_t)__builtin_arm_ldrex
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB (uint32_t)__builtin_arm_strex
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH (uint32_t)__builtin_arm_strex
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW (uint32_t)__builtin_arm_strex
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __builtin_arm_clrex
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __builtin_arm_ssat
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __builtin_arm_usat
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1))
#define __SADD8 __builtin_arm_sadd8
#define __SADD16 __builtin_arm_sadd16
#define __QADD8 __builtin_arm_qadd8
#define __QSUB8 __builtin_arm_qsub8
#define __QADD16 __builtin_arm_qadd16
#define __SHADD16 __builtin_arm_shadd16
#define __QSUB16 __builtin_arm_qsub16
#define __SHSUB16 __builtin_arm_shsub16
#define __QASX __builtin_arm_qasx
#define __SHASX __builtin_arm_shasx
#define __QSAX __builtin_arm_qsax
#define __SHSAX __builtin_arm_shsax
#define __SXTB16 __builtin_arm_sxtb16
#define __SMUAD __builtin_arm_smuad
#define __SMUADX __builtin_arm_smuadx
#define __SMLAD __builtin_arm_smlad
#define __SMLADX __builtin_arm_smladx
#define __SMLALD __builtin_arm_smlald
#define __SMLALDX __builtin_arm_smlaldx
#define __SMUSD __builtin_arm_smusd
#define __SMUSDX __builtin_arm_smusdx
#define __SMLSDX __builtin_arm_smlsdx
#define __USAT16 __builtin_arm_usat16
#define __SSUB8 __builtin_arm_ssub8
#define __SXTB16 __builtin_arm_sxtb16
#define __SXTAB16 __builtin_arm_sxtab16
__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2)
{
int32_t result;
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2)
{
int32_t result;
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
{
int32_t result;
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#endif /* (__ARM_FEATURE_DSP == 1) */
/* ########################### Core Function Access ########################### */
/**
\brief Enable IRQ Interrupts
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__STATIC_FORCEINLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i" : : : "memory");
}
/**
\brief Disable IRQ Interrupts
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__STATIC_FORCEINLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i" : : : "memory");
}
/**
\brief Enable FIQ
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__STATIC_FORCEINLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f" : : : "memory");
}
/**
\brief Disable FIQ
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__STATIC_FORCEINLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f" : : : "memory");
}
/**
\brief Get FPSCR
\details Returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
#define __get_FPSCR __builtin_arm_get_fpscr
/**
\brief Set FPSCR
\details Assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
#define __set_FPSCR __builtin_arm_set_fpscr
/** \brief Get CPSR Register
\return CPSR Register value
*/
__STATIC_FORCEINLINE uint32_t __get_CPSR(void)
{
uint32_t result;
__ASM volatile("MRS %0, cpsr" : "=r" (result) );
return(result);
}
/** \brief Set CPSR Register
\param [in] cpsr CPSR value to set
*/
__STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr)
{
__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "cc", "memory");
}
/** \brief Get Mode
\return Processor Mode
*/
__STATIC_FORCEINLINE uint32_t __get_mode(void)
{
return (__get_CPSR() & 0x1FU);
}
/** \brief Set Mode
\param [in] mode Mode value to set
*/
__STATIC_FORCEINLINE void __set_mode(uint32_t mode)
{
__ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory");
}
/** \brief Get Stack Pointer
\return Stack Pointer value
*/
__STATIC_FORCEINLINE uint32_t __get_SP(void)
{
uint32_t result;
__ASM volatile("MOV %0, sp" : "=r" (result) : : "memory");
return result;
}
/** \brief Set Stack Pointer
\param [in] stack Stack Pointer value to set
*/
__STATIC_FORCEINLINE void __set_SP(uint32_t stack)
{
__ASM volatile("MOV sp, %0" : : "r" (stack) : "memory");
}
/** \brief Get USR/SYS Stack Pointer
\return USR/SYS Stack Pointer value
*/
__STATIC_FORCEINLINE uint32_t __get_SP_usr(void)
{
uint32_t cpsr;
uint32_t result;
__ASM volatile(
"MRS %0, cpsr \n"
"CPS #0x1F \n" // no effect in USR mode
"MOV %1, sp \n"
"MSR cpsr_c, %0 \n" // no effect in USR mode
"ISB" : "=r"(cpsr), "=r"(result) : : "memory"
);
return result;
}
/** \brief Set USR/SYS Stack Pointer
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
*/
__STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack)
{
uint32_t cpsr;
__ASM volatile(
"MRS %0, cpsr \n"
"CPS #0x1F \n" // no effect in USR mode
"MOV sp, %1 \n"
"MSR cpsr_c, %0 \n" // no effect in USR mode
"ISB" : "=r"(cpsr) : "r" (topOfProcStack) : "memory"
);
}
/** \brief Get FPEXC
\return Floating Point Exception Control register value
*/
__STATIC_FORCEINLINE uint32_t __get_FPEXC(void)
{
#if (__FPU_PRESENT == 1)
uint32_t result;
__ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory");
return(result);
#else
return(0);
#endif
}
/** \brief Set FPEXC
\param [in] fpexc Floating Point Exception Control value to set
*/
__STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc)
{
#if (__FPU_PRESENT == 1)
__ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory");
#endif
}
/*
* Include common core functions to access Coprocessor 15 registers
*/
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" )
#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" )
#define __get_CP64(cp, op1, Rt, CRm) __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" )
#define __set_CP64(cp, op1, Rt, CRm) __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" )
#include "cmsis_cp15.h"
/** \brief Enable Floating Point Unit
Critical section, called from undef handler, so systick is disabled
*/
__STATIC_INLINE void __FPU_Enable(void)
{
__ASM volatile(
//Permit access to VFP/NEON, registers by modifying CPACR
" MRC p15,0,R1,c1,c0,2 \n"
" ORR R1,R1,#0x00F00000 \n"
" MCR p15,0,R1,c1,c0,2 \n"
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
" ISB \n"
//Enable VFP/NEON
" VMRS R1,FPEXC \n"
" ORR R1,R1,#0x40000000 \n"
" VMSR FPEXC,R1 \n"
//Initialise VFP/NEON registers to 0
" MOV R2,#0 \n"
//Initialise D16 registers to 0
" VMOV D0, R2,R2 \n"
" VMOV D1, R2,R2 \n"
" VMOV D2, R2,R2 \n"
" VMOV D3, R2,R2 \n"
" VMOV D4, R2,R2 \n"
" VMOV D5, R2,R2 \n"
" VMOV D6, R2,R2 \n"
" VMOV D7, R2,R2 \n"
" VMOV D8, R2,R2 \n"
" VMOV D9, R2,R2 \n"
" VMOV D10,R2,R2 \n"
" VMOV D11,R2,R2 \n"
" VMOV D12,R2,R2 \n"
" VMOV D13,R2,R2 \n"
" VMOV D14,R2,R2 \n"
" VMOV D15,R2,R2 \n"
#if (defined(__ARM_NEON) && (__ARM_NEON == 1))
//Initialise D32 registers to 0
" VMOV D16,R2,R2 \n"
" VMOV D17,R2,R2 \n"
" VMOV D18,R2,R2 \n"
" VMOV D19,R2,R2 \n"
" VMOV D20,R2,R2 \n"
" VMOV D21,R2,R2 \n"
" VMOV D22,R2,R2 \n"
" VMOV D23,R2,R2 \n"
" VMOV D24,R2,R2 \n"
" VMOV D25,R2,R2 \n"
" VMOV D26,R2,R2 \n"
" VMOV D27,R2,R2 \n"
" VMOV D28,R2,R2 \n"
" VMOV D29,R2,R2 \n"
" VMOV D30,R2,R2 \n"
" VMOV D31,R2,R2 \n"
#endif
//Initialise FPSCR to a known state
" VMRS R1,FPSCR \n"
" LDR R2,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
" AND R1,R1,R2 \n"
" VMSR FPSCR,R1 "
: : : "cc", "r1", "r2"
);
}
#endif /* __CMSIS_ARMCLANG_H */
@@ -0,0 +1,213 @@
/**************************************************************************//**
* @file cmsis_compiler.h
* @brief CMSIS compiler specific macros, functions, instructions
* @version V1.0.2
* @date 10. January 2018
******************************************************************************/
/*
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CMSIS_COMPILER_H
#define __CMSIS_COMPILER_H
#include <stdint.h>
/*
* Arm Compiler 4/5
*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*
* Arm Compiler 6 (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armclang.h"
/*
* GNU Compiler
*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*
* IAR Compiler
*/
#elif defined ( __ICCARM__ )
#include "cmsis_iccarm.h"
/*
* TI Arm Compiler
*/
#elif defined ( __TI_ARM__ )
#include <cmsis_ccs.h>
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef CMSIS_DEPRECATED
#define CMSIS_DEPRECATED __attribute__((deprecated))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __UNALIGNED_UINT32
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
/*
* TASKING Compiler
*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef CMSIS_DEPRECATED
#define CMSIS_DEPRECATED __attribute__((deprecated))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __UNALIGNED_UINT32
struct __packed__ T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __align(x)
#endif
#ifndef __PACKED
#define __PACKED __packed__
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
/*
* COSMIC Compiler
*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#ifndef __ASM
#define __ASM _asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
// NO RETURN is automatically detected hence no warning here
#define __NO_RETURN
#endif
#ifndef __USED
#warning No compiler specific solution for __USED. __USED is ignored.
#define __USED
#endif
#ifndef CMSIS_DEPRECATED
#warning No compiler specific solution for CMSIS_DEPRECATED. CMSIS_DEPRECATED is ignored.
#define CMSIS_DEPRECATED
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __UNALIGNED_UINT32
@packed struct T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __ALIGNED
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#ifndef __PACKED
#define __PACKED @packed
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
#else
#error Unknown compiler.
#endif
#endif /* __CMSIS_COMPILER_H */
@@ -0,0 +1,514 @@
/**************************************************************************//**
* @file cmsis_cp15.h
* @brief CMSIS compiler specific macros, functions, instructions
* @version V1.0.1
* @date 07. Sep 2017
******************************************************************************/
/*
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CMSIS_CP15_H
#define __CMSIS_CP15_H
/** \brief Get ACTLR
\return Auxiliary Control register value
*/
__STATIC_FORCEINLINE uint32_t __get_ACTLR(void)
{
uint32_t result;
__get_CP(15, 0, result, 1, 0, 1);
return(result);
}
/** \brief Set ACTLR
\param [in] actlr Auxiliary Control value to set
*/
__STATIC_FORCEINLINE void __set_ACTLR(uint32_t actlr)
{
__set_CP(15, 0, actlr, 1, 0, 1);
}
/** \brief Get CPACR
\return Coprocessor Access Control register value
*/
__STATIC_FORCEINLINE uint32_t __get_CPACR(void)
{
uint32_t result;
__get_CP(15, 0, result, 1, 0, 2);
return result;
}
/** \brief Set CPACR
\param [in] cpacr Coprocessor Access Control value to set
*/
__STATIC_FORCEINLINE void __set_CPACR(uint32_t cpacr)
{
__set_CP(15, 0, cpacr, 1, 0, 2);
}
/** \brief Get DFSR
\return Data Fault Status Register value
*/
__STATIC_FORCEINLINE uint32_t __get_DFSR(void)
{
uint32_t result;
__get_CP(15, 0, result, 5, 0, 0);
return result;
}
/** \brief Set DFSR
\param [in] dfsr Data Fault Status value to set
*/
__STATIC_FORCEINLINE void __set_DFSR(uint32_t dfsr)
{
__set_CP(15, 0, dfsr, 5, 0, 0);
}
/** \brief Get IFSR
\return Instruction Fault Status Register value
*/
__STATIC_FORCEINLINE uint32_t __get_IFSR(void)
{
uint32_t result;
__get_CP(15, 0, result, 5, 0, 1);
return result;
}
/** \brief Set IFSR
\param [in] ifsr Instruction Fault Status value to set
*/
__STATIC_FORCEINLINE void __set_IFSR(uint32_t ifsr)
{
__set_CP(15, 0, ifsr, 5, 0, 1);
}
/** \brief Get ISR
\return Interrupt Status Register value
*/
__STATIC_FORCEINLINE uint32_t __get_ISR(void)
{
uint32_t result;
__get_CP(15, 0, result, 12, 1, 0);
return result;
}
/** \brief Get CBAR
\return Configuration Base Address register value
*/
__STATIC_FORCEINLINE uint32_t __get_CBAR(void)
{
uint32_t result;
__get_CP(15, 4, result, 15, 0, 0);
return result;
}
/** \brief Get TTBR0
This function returns the value of the Translation Table Base Register 0.
\return Translation Table Base Register 0 value
*/
__STATIC_FORCEINLINE uint32_t __get_TTBR0(void)
{
uint32_t result;
__get_CP(15, 0, result, 2, 0, 0);
return result;
}
/** \brief Set TTBR0
This function assigns the given value to the Translation Table Base Register 0.
\param [in] ttbr0 Translation Table Base Register 0 value to set
*/
__STATIC_FORCEINLINE void __set_TTBR0(uint32_t ttbr0)
{
__set_CP(15, 0, ttbr0, 2, 0, 0);
}
/** \brief Get DACR
This function returns the value of the Domain Access Control Register.
\return Domain Access Control Register value
*/
__STATIC_FORCEINLINE uint32_t __get_DACR(void)
{
uint32_t result;
__get_CP(15, 0, result, 3, 0, 0);
return result;
}
/** \brief Set DACR
This function assigns the given value to the Domain Access Control Register.
\param [in] dacr Domain Access Control Register value to set
*/
__STATIC_FORCEINLINE void __set_DACR(uint32_t dacr)
{
__set_CP(15, 0, dacr, 3, 0, 0);
}
/** \brief Set SCTLR
This function assigns the given value to the System Control Register.
\param [in] sctlr System Control Register value to set
*/
__STATIC_FORCEINLINE void __set_SCTLR(uint32_t sctlr)
{
__set_CP(15, 0, sctlr, 1, 0, 0);
}
/** \brief Get SCTLR
\return System Control Register value
*/
__STATIC_FORCEINLINE uint32_t __get_SCTLR(void)
{
uint32_t result;
__get_CP(15, 0, result, 1, 0, 0);
return result;
}
/** \brief Set ACTRL
\param [in] actrl Auxiliary Control Register value to set
*/
__STATIC_FORCEINLINE void __set_ACTRL(uint32_t actrl)
{
__set_CP(15, 0, actrl, 1, 0, 1);
}
/** \brief Get ACTRL
\return Auxiliary Control Register value
*/
__STATIC_FORCEINLINE uint32_t __get_ACTRL(void)
{
uint32_t result;
__get_CP(15, 0, result, 1, 0, 1);
return result;
}
/** \brief Get MPIDR
This function returns the value of the Multiprocessor Affinity Register.
\return Multiprocessor Affinity Register value
*/
__STATIC_FORCEINLINE uint32_t __get_MPIDR(void)
{
uint32_t result;
__get_CP(15, 0, result, 0, 0, 5);
return result;
}
/** \brief Get VBAR
This function returns the value of the Vector Base Address Register.
\return Vector Base Address Register
*/
__STATIC_FORCEINLINE uint32_t __get_VBAR(void)
{
uint32_t result;
__get_CP(15, 0, result, 12, 0, 0);
return result;
}
/** \brief Set VBAR
This function assigns the given value to the Vector Base Address Register.
\param [in] vbar Vector Base Address Register value to set
*/
__STATIC_FORCEINLINE void __set_VBAR(uint32_t vbar)
{
__set_CP(15, 0, vbar, 12, 0, 0);
}
/** \brief Get MVBAR
This function returns the value of the Monitor Vector Base Address Register.
\return Monitor Vector Base Address Register
*/
__STATIC_FORCEINLINE uint32_t __get_MVBAR(void)
{
uint32_t result;
__get_CP(15, 0, result, 12, 0, 1);
return result;
}
/** \brief Set MVBAR
This function assigns the given value to the Monitor Vector Base Address Register.
\param [in] mvbar Monitor Vector Base Address Register value to set
*/
__STATIC_FORCEINLINE void __set_MVBAR(uint32_t mvbar)
{
__set_CP(15, 0, mvbar, 12, 0, 1);
}
#if (defined(__CORTEX_A) && (__CORTEX_A == 7U) && \
defined(__TIM_PRESENT) && (__TIM_PRESENT == 1U)) || \
defined(DOXYGEN)
/** \brief Set CNTFRQ
This function assigns the given value to PL1 Physical Timer Counter Frequency Register (CNTFRQ).
\param [in] value CNTFRQ Register value to set
*/
__STATIC_FORCEINLINE void __set_CNTFRQ(uint32_t value)
{
__set_CP(15, 0, value, 14, 0, 0);
}
/** \brief Get CNTFRQ
This function returns the value of the PL1 Physical Timer Counter Frequency Register (CNTFRQ).
\return CNTFRQ Register value
*/
__STATIC_FORCEINLINE uint32_t __get_CNTFRQ(void)
{
uint32_t result;
__get_CP(15, 0, result, 14, 0 , 0);
return result;
}
/** \brief Set CNTP_TVAL
This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL).
\param [in] value CNTP_TVAL Register value to set
*/
__STATIC_FORCEINLINE void __set_CNTP_TVAL(uint32_t value)
{
__set_CP(15, 0, value, 14, 2, 0);
}
/** \brief Get CNTP_TVAL
This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL).
\return CNTP_TVAL Register value
*/
__STATIC_FORCEINLINE uint32_t __get_CNTP_TVAL(void)
{
uint32_t result;
__get_CP(15, 0, result, 14, 2, 0);
return result;
}
/** \brief Get CNTPCT
This function returns the value of the 64 bits PL1 Physical Count Register (CNTPCT).
\return CNTPCT Register value
*/
__STATIC_FORCEINLINE uint64_t __get_CNTPCT(void)
{
uint64_t result;
__get_CP64(15, 0, result, 14);
return result;
}
/** \brief Set CNTP_CVAL
This function assigns the given value to 64bits PL1 Physical Timer CompareValue Register (CNTP_CVAL).
\param [in] value CNTP_CVAL Register value to set
*/
__STATIC_FORCEINLINE void __set_CNTP_CVAL(uint64_t value)
{
__set_CP64(15, 2, value, 14);
}
/** \brief Get CNTP_CVAL
This function returns the value of the 64 bits PL1 Physical Timer CompareValue Register (CNTP_CVAL).
\return CNTP_CVAL Register value
*/
__STATIC_FORCEINLINE uint64_t __get_CNTP_CVAL(void)
{
uint64_t result;
__get_CP64(15, 2, result, 14);
return result;
}
/** \brief Set CNTP_CTL
This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL).
\param [in] value CNTP_CTL Register value to set
*/
__STATIC_FORCEINLINE void __set_CNTP_CTL(uint32_t value)
{
__set_CP(15, 0, value, 14, 2, 1);
}
/** \brief Get CNTP_CTL register
\return CNTP_CTL Register value
*/
__STATIC_FORCEINLINE uint32_t __get_CNTP_CTL(void)
{
uint32_t result;
__get_CP(15, 0, result, 14, 2, 1);
return result;
}
#endif
/** \brief Set TLBIALL
TLB Invalidate All
*/
__STATIC_FORCEINLINE void __set_TLBIALL(uint32_t value)
{
__set_CP(15, 0, value, 8, 7, 0);
}
/** \brief Set BPIALL.
Branch Predictor Invalidate All
*/
__STATIC_FORCEINLINE void __set_BPIALL(uint32_t value)
{
__set_CP(15, 0, value, 7, 5, 6);
}
/** \brief Set ICIALLU
Instruction Cache Invalidate All
*/
__STATIC_FORCEINLINE void __set_ICIALLU(uint32_t value)
{
__set_CP(15, 0, value, 7, 5, 0);
}
/** \brief Set DCCMVAC
Data cache clean
*/
__STATIC_FORCEINLINE void __set_DCCMVAC(uint32_t value)
{
__set_CP(15, 0, value, 7, 10, 1);
}
/** \brief Set DCIMVAC
Data cache invalidate
*/
__STATIC_FORCEINLINE void __set_DCIMVAC(uint32_t value)
{
__set_CP(15, 0, value, 7, 6, 1);
}
/** \brief Set DCCIMVAC
Data cache clean and invalidate
*/
__STATIC_FORCEINLINE void __set_DCCIMVAC(uint32_t value)
{
__set_CP(15, 0, value, 7, 14, 1);
}
/** \brief Set CSSELR
*/
__STATIC_FORCEINLINE void __set_CSSELR(uint32_t value)
{
// __ASM volatile("MCR p15, 2, %0, c0, c0, 0" : : "r"(value) : "memory");
__set_CP(15, 2, value, 0, 0, 0);
}
/** \brief Get CSSELR
\return CSSELR Register value
*/
__STATIC_FORCEINLINE uint32_t __get_CSSELR(void)
{
uint32_t result;
// __ASM volatile("MRC p15, 2, %0, c0, c0, 0" : "=r"(result) : : "memory");
__get_CP(15, 2, result, 0, 0, 0);
return result;
}
/** \brief Set CCSIDR
\deprecated CCSIDR itself is read-only. Use __set_CSSELR to select cache level instead.
*/
CMSIS_DEPRECATED
__STATIC_FORCEINLINE void __set_CCSIDR(uint32_t value)
{
__set_CSSELR(value);
}
/** \brief Get CCSIDR
\return CCSIDR Register value
*/
__STATIC_FORCEINLINE uint32_t __get_CCSIDR(void)
{
uint32_t result;
// __ASM volatile("MRC p15, 1, %0, c0, c0, 0" : "=r"(result) : : "memory");
__get_CP(15, 1, result, 0, 0, 0);
return result;
}
/** \brief Get CLIDR
\return CLIDR Register value
*/
__STATIC_FORCEINLINE uint32_t __get_CLIDR(void)
{
uint32_t result;
// __ASM volatile("MRC p15, 1, %0, c0, c0, 1" : "=r"(result) : : "memory");
__get_CP(15, 1, result, 0, 0, 1);
return result;
}
/** \brief Set DCISW
*/
__STATIC_FORCEINLINE void __set_DCISW(uint32_t value)
{
// __ASM volatile("MCR p15, 0, %0, c7, c6, 2" : : "r"(value) : "memory")
__set_CP(15, 0, value, 7, 6, 2);
}
/** \brief Set DCCSW
*/
__STATIC_FORCEINLINE void __set_DCCSW(uint32_t value)
{
// __ASM volatile("MCR p15, 0, %0, c7, c10, 2" : : "r"(value) : "memory")
__set_CP(15, 0, value, 7, 10, 2);
}
/** \brief Set DCCISW
*/
__STATIC_FORCEINLINE void __set_DCCISW(uint32_t value)
{
// __ASM volatile("MCR p15, 0, %0, c7, c14, 2" : : "r"(value) : "memory")
__set_CP(15, 0, value, 7, 14, 2);
}
#endif
@@ -0,0 +1,917 @@
/**************************************************************************//**
* @file cmsis_gcc.h
* @brief CMSIS compiler specific macros, functions, instructions
* @version V1.3.2
* @date 24. March 2022
******************************************************************************/
/*
* Copyright (c) 2009-2022 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CMSIS_GCC_H
#define __CMSIS_GCC_H
/* ignore some GCC warnings */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wunused-parameter"
/* Fallback for __has_builtin */
#ifndef __has_builtin
#define __has_builtin(x) (0)
#endif
/* CMSIS compiler specific defines */
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __FORCEINLINE
#define __FORCEINLINE __attribute__((always_inline))
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((__noreturn__))
#endif
#ifndef CMSIS_DEPRECATED
#define CMSIS_DEPRECATED __attribute__((deprecated))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed, aligned(1)))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpacked"
/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#pragma GCC diagnostic pop
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpacked"
/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#pragma GCC diagnostic pop
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpacked"
/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#pragma GCC diagnostic pop
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpacked"
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#pragma GCC diagnostic pop
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __COMPILER_BARRIER
#define __COMPILER_BARRIER() __ASM volatile("":::"memory")
#endif
__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2)
{
int32_t result;
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ /* Little endian */
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else /* Big endian */
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2)
{
int32_t result;
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1)
{
uint32_t result;
__ASM ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ /* Little endian */
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else /* Big endian */
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
{
int32_t result;
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
/* ########################## Core Instruction Access ######################### */
/**
\brief No Operation
*/
#define __NOP() __ASM volatile ("nop")
/**
\brief Wait For Interrupt
*/
#define __WFI() __ASM volatile ("wfi":::"memory")
/**
\brief Wait For Event
*/
#define __WFE() __ASM volatile ("wfe":::"memory")
/**
\brief Send Event
*/
#define __SEV() __ASM volatile ("sev")
/**
\brief Instruction Synchronization Barrier
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or memory,
after the instruction has been completed.
*/
__STATIC_FORCEINLINE void __ISB(void)
{
__ASM volatile ("isb 0xF":::"memory");
}
/**
\brief Data Synchronization Barrier
\details Acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__STATIC_FORCEINLINE void __DSB(void)
{
__ASM volatile ("dsb 0xF":::"memory");
}
/**
\brief Data Memory Barrier
\details Ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__STATIC_FORCEINLINE void __DMB(void)
{
__ASM volatile ("dmb 0xF":::"memory");
}
/**
\brief Reverse byte order (32 bit)
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
\param [in] value Value to reverse
\return Reversed value
*/
__STATIC_FORCEINLINE uint32_t __REV(uint32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
return __builtin_bswap32(value);
#else
uint32_t result;
__ASM ("rev %0, %1" : "=r" (result) : "r" (value) );
return result;
#endif
}
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
\param [in] value Value to reverse
\return Reversed value
*/
__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM ("rev16 %0, %1" : "=r" (result) : "r" (value));
return result;
}
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
\param [in] value Value to reverse
\return Reversed value
*/
__STATIC_FORCEINLINE int16_t __REVSH(int16_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
return (int16_t)__builtin_bswap16(value);
#else
int16_t result;
__ASM ("revsh %0, %1" : "=r" (result) : "r" (value) );
return result;
#endif
}
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] op1 Value to rotate
\param [in] op2 Number of Bits to rotate
\return Rotated value
*/
__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
op2 %= 32U;
if (op2 == 0U)
{
return op1;
}
return (op1 >> op2) | (op1 << (32U - op2));
}
/**
\brief Breakpoint
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __ASM volatile ("bkpt "#value)
/**
\brief Reverse bit order of value
\details Reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM ("rbit %0, %1" : "=r" (result) : "r" (value) );
return result;
}
/**
\brief Count leading zeros
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value)
{
/* Even though __builtin_clz produces a CLZ instruction on ARM, formally
__builtin_clz(0) is undefined behaviour, so handle this case specially.
This guarantees ARM-compatible results if happening to compile on a non-ARM
target, and ensures the compiler doesn't decide to activate any
optimisations using the logic "value was passed to __builtin_clz, so it
is non-zero".
ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a
single CLZ instruction.
*/
if (value == 0U)
{
return 32U;
}
return __builtin_clz(value);
}
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint8_t) result); /* Add explicit type cast here */
}
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint16_t) result); /* Add explicit type cast here */
}
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
return(result);
}
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
return(result);
}
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
return(result);
}
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
return(result);
}
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
__STATIC_FORCEINLINE void __CLREX(void)
{
__ASM volatile ("clrex" ::: "memory");
}
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1, ARG2) \
__extension__ \
({ \
int32_t __RES, __ARG1 = (ARG1); \
__ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \
__RES; \
})
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1, ARG2) \
__extension__ \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM volatile ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \
__RES; \
})
/* ########################### Core Function Access ########################### */
/**
\brief Enable IRQ Interrupts
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__STATIC_FORCEINLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i" : : : "memory");
}
/**
\brief Disable IRQ Interrupts
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__STATIC_FORCEINLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i" : : : "memory");
}
/**
\brief Enable FIQ
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__STATIC_FORCEINLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f" : : : "memory");
}
/**
\brief Disable FIQ
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__STATIC_FORCEINLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f" : : : "memory");
}
/**
\brief Get FPSCR
\details Returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_FORCEINLINE uint32_t __get_FPSCR(void)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
#if __has_builtin(__builtin_arm_get_fpscr)
// Re-enable using built-in when GCC has been fixed
// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
/* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
return __builtin_arm_get_fpscr();
#else
uint32_t result;
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
return(result);
#endif
#else
return(0U);
#endif
}
/**
\brief Set FPSCR
\details Assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
#if __has_builtin(__builtin_arm_set_fpscr)
// Re-enable using built-in when GCC has been fixed
// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
/* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
__builtin_arm_set_fpscr(fpscr);
#else
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory");
#endif
#else
(void)fpscr;
#endif
}
/** \brief Get CPSR Register
\return CPSR Register value
*/
__STATIC_FORCEINLINE uint32_t __get_CPSR(void)
{
uint32_t result;
__ASM volatile("MRS %0, cpsr" : "=r" (result) );
return(result);
}
/** \brief Set CPSR Register
\param [in] cpsr CPSR value to set
*/
__STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr)
{
__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "cc", "memory");
}
/** \brief Get Mode
\return Processor Mode
*/
__STATIC_FORCEINLINE uint32_t __get_mode(void)
{
return (__get_CPSR() & 0x1FU);
}
/** \brief Set Mode
\param [in] mode Mode value to set
*/
__STATIC_FORCEINLINE void __set_mode(uint32_t mode)
{
__ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory");
}
/** \brief Get Stack Pointer
\return Stack Pointer value
*/
__STATIC_FORCEINLINE uint32_t __get_SP(void)
{
uint32_t result;
__ASM volatile("MOV %0, sp" : "=r" (result) : : "memory");
return result;
}
/** \brief Set Stack Pointer
\param [in] stack Stack Pointer value to set
*/
__STATIC_FORCEINLINE void __set_SP(uint32_t stack)
{
__ASM volatile("MOV sp, %0" : : "r" (stack) : "memory");
}
/** \brief Get USR/SYS Stack Pointer
\return USR/SYS Stack Pointer value
*/
__STATIC_FORCEINLINE uint32_t __get_SP_usr(void)
{
uint32_t cpsr = __get_CPSR();
uint32_t result;
__ASM volatile(
"CPS #0x1F \n"
"MOV %0, sp " : "=r"(result) : : "memory"
);
__set_CPSR(cpsr);
__ISB();
return result;
}
/** \brief Set USR/SYS Stack Pointer
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
*/
__STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack)
{
uint32_t cpsr = __get_CPSR();
__ASM volatile(
"CPS #0x1F \n"
"MOV sp, %0 " : : "r" (topOfProcStack) : "memory"
);
__set_CPSR(cpsr);
__ISB();
}
/** \brief Get FPEXC
\return Floating Point Exception Control register value
*/
__STATIC_FORCEINLINE uint32_t __get_FPEXC(void)
{
#if (__FPU_PRESENT == 1)
uint32_t result;
__ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory");
return(result);
#else
return(0);
#endif
}
/** \brief Set FPEXC
\param [in] fpexc Floating Point Exception Control value to set
*/
__STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc)
{
#if (__FPU_PRESENT == 1)
__ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory");
#endif
}
/*
* Include common core functions to access Coprocessor 15 registers
*/
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" )
#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" )
#define __get_CP64(cp, op1, Rt, CRm) __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" )
#define __set_CP64(cp, op1, Rt, CRm) __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" )
#include "cmsis_cp15.h"
/** \brief Enable Floating Point Unit
Critical section, called from undef handler, so systick is disabled
*/
__STATIC_INLINE void __FPU_Enable(void)
{
__ASM volatile(
//Permit access to VFP/NEON, registers by modifying CPACR
" MRC p15,0,R1,c1,c0,2 \n"
" ORR R1,R1,#0x00F00000 \n"
" MCR p15,0,R1,c1,c0,2 \n"
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
" ISB \n"
//Enable VFP/NEON
" VMRS R1,FPEXC \n"
" ORR R1,R1,#0x40000000 \n"
" VMSR FPEXC,R1 \n"
//Initialise VFP/NEON registers to 0
" MOV R2,#0 \n"
//Initialise D16 registers to 0
" VMOV D0, R2,R2 \n"
" VMOV D1, R2,R2 \n"
" VMOV D2, R2,R2 \n"
" VMOV D3, R2,R2 \n"
" VMOV D4, R2,R2 \n"
" VMOV D5, R2,R2 \n"
" VMOV D6, R2,R2 \n"
" VMOV D7, R2,R2 \n"
" VMOV D8, R2,R2 \n"
" VMOV D9, R2,R2 \n"
" VMOV D10,R2,R2 \n"
" VMOV D11,R2,R2 \n"
" VMOV D12,R2,R2 \n"
" VMOV D13,R2,R2 \n"
" VMOV D14,R2,R2 \n"
" VMOV D15,R2,R2 \n"
#if (defined(__ARM_NEON) && (__ARM_NEON == 1))
//Initialise D32 registers to 0
" VMOV D16,R2,R2 \n"
" VMOV D17,R2,R2 \n"
" VMOV D18,R2,R2 \n"
" VMOV D19,R2,R2 \n"
" VMOV D20,R2,R2 \n"
" VMOV D21,R2,R2 \n"
" VMOV D22,R2,R2 \n"
" VMOV D23,R2,R2 \n"
" VMOV D24,R2,R2 \n"
" VMOV D25,R2,R2 \n"
" VMOV D26,R2,R2 \n"
" VMOV D27,R2,R2 \n"
" VMOV D28,R2,R2 \n"
" VMOV D29,R2,R2 \n"
" VMOV D30,R2,R2 \n"
" VMOV D31,R2,R2 \n"
#endif
//Initialise FPSCR to a known state
" VMRS R1,FPSCR \n"
" LDR R2,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
" AND R1,R1,R2 \n"
" VMSR FPSCR,R1 "
: : : "cc", "r1", "r2"
);
}
#pragma GCC diagnostic pop
#endif /* __CMSIS_GCC_H */
@@ -0,0 +1,573 @@
/**************************************************************************//**
* @file cmsis_iccarm.h
* @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file
* @version V5.0.7
* @date 15. May 2019
******************************************************************************/
//------------------------------------------------------------------------------
//
// Copyright (c) 2017-2018 IAR Systems
// Copyright (c) 2018-2019 Arm Limited
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License")
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//------------------------------------------------------------------------------
#ifndef __CMSIS_ICCARM_H__
#define __CMSIS_ICCARM_H__
#ifndef __ICCARM__
#error This file should only be compiled by ICCARM
#endif
#pragma system_include
#define __IAR_FT _Pragma("inline=forced") __intrinsic
#if (__VER__ >= 8000000)
#define __ICCARM_V8 1
#else
#define __ICCARM_V8 0
#endif
#pragma language=extended
#ifndef __ALIGNED
#if __ICCARM_V8
#define __ALIGNED(x) __attribute__((aligned(x)))
#elif (__VER__ >= 7080000)
/* Needs IAR language extensions */
#define __ALIGNED(x) __attribute__((aligned(x)))
#else
#warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#endif
/* Define compiler macros for CPU architecture, used in CMSIS 5.
*/
#if __ARM_ARCH_7A__
/* Macro already defined */
#else
#if defined(__ARM7A__)
#define __ARM_ARCH_7A__ 1
#endif
#endif
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __COMPILER_BARRIER
#define __COMPILER_BARRIER() __ASM volatile("":::"memory")
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __NO_RETURN
#if __ICCARM_V8
#define __NO_RETURN __attribute__((__noreturn__))
#else
#define __NO_RETURN _Pragma("object_attribute=__noreturn")
#endif
#endif
#ifndef __PACKED
/* Needs IAR language extensions */
#if __ICCARM_V8
#define __PACKED __attribute__((packed, aligned(1)))
#else
#define __PACKED __packed
#endif
#endif
#ifndef __PACKED_STRUCT
/* Needs IAR language extensions */
#if __ICCARM_V8
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
#else
#define __PACKED_STRUCT __packed struct
#endif
#endif
#ifndef __PACKED_UNION
/* Needs IAR language extensions */
#if __ICCARM_V8
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
#else
#define __PACKED_UNION __packed union
#endif
#endif
#ifndef __RESTRICT
#if __ICCARM_V8
#define __RESTRICT __restrict
#else
/* Needs IAR language extensions */
#define __RESTRICT restrict
#endif
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __FORCEINLINE
#define __FORCEINLINE _Pragma("inline=forced")
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE
#endif
#ifndef CMSIS_DEPRECATED
#define CMSIS_DEPRECATED __attribute__((deprecated))
#endif
#ifndef __UNALIGNED_UINT16_READ
#pragma language=save
#pragma language=extended
__IAR_FT uint16_t __iar_uint16_read(void const *ptr)
{
return *(__packed uint16_t*)(ptr);
}
#pragma language=restore
#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#pragma language=save
#pragma language=extended
__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val)
{
*(__packed uint16_t*)(ptr) = val;;
}
#pragma language=restore
#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL)
#endif
#ifndef __UNALIGNED_UINT32_READ
#pragma language=save
#pragma language=extended
__IAR_FT uint32_t __iar_uint32_read(void const *ptr)
{
return *(__packed uint32_t*)(ptr);
}
#pragma language=restore
#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#pragma language=save
#pragma language=extended
__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val)
{
*(__packed uint32_t*)(ptr) = val;;
}
#pragma language=restore
#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL)
#endif
#if 0
#ifndef __UNALIGNED_UINT32 /* deprecated */
#pragma language=save
#pragma language=extended
__packed struct __iar_u32 { uint32_t v; };
#pragma language=restore
#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v)
#endif
#endif
#ifndef __USED
#if __ICCARM_V8
#define __USED __attribute__((used))
#else
#define __USED _Pragma("__root")
#endif
#endif
#ifndef __WEAK
#if __ICCARM_V8
#define __WEAK __attribute__((weak))
#else
#define __WEAK _Pragma("__weak")
#endif
#endif
#ifndef __ICCARM_INTRINSICS_VERSION__
#define __ICCARM_INTRINSICS_VERSION__ 0
#endif
#if __ICCARM_INTRINSICS_VERSION__ == 2
#if defined(__CLZ)
#undef __CLZ
#endif
#if defined(__REVSH)
#undef __REVSH
#endif
#if defined(__RBIT)
#undef __RBIT
#endif
#if defined(__SSAT)
#undef __SSAT
#endif
#if defined(__USAT)
#undef __USAT
#endif
#include "iccarm_builtin.h"
#define __enable_irq __iar_builtin_enable_interrupt
#define __disable_irq __iar_builtin_disable_interrupt
#define __enable_fault_irq __iar_builtin_enable_fiq
#define __disable_fault_irq __iar_builtin_disable_fiq
#define __arm_rsr __iar_builtin_rsr
#define __arm_wsr __iar_builtin_wsr
#if __FPU_PRESENT
#define __get_FPSCR() (__arm_rsr("FPSCR"))
#else
#define __get_FPSCR() ( 0 )
#endif
#define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", VALUE))
#define __get_CPSR() (__arm_rsr("CPSR"))
#define __get_mode() (__get_CPSR() & 0x1FU)
#define __set_CPSR(VALUE) (__arm_wsr("CPSR", (VALUE)))
#define __set_mode(VALUE) (__arm_wsr("CPSR_c", (VALUE)))
#define __get_FPEXC() (__arm_rsr("FPEXC"))
#define __set_FPEXC(VALUE) (__arm_wsr("FPEXC", VALUE))
#define __get_CP(cp, op1, RT, CRn, CRm, op2) \
((RT) = __arm_rsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2))
#define __set_CP(cp, op1, RT, CRn, CRm, op2) \
(__arm_wsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2, (RT)))
#define __get_CP64(cp, op1, Rt, CRm) \
__ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" )
#define __set_CP64(cp, op1, Rt, CRm) \
__ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" )
#include "cmsis_cp15.h"
#define __NOP __iar_builtin_no_operation
#define __CLZ __iar_builtin_CLZ
#define __CLREX __iar_builtin_CLREX
#define __DMB __iar_builtin_DMB
#define __DSB __iar_builtin_DSB
#define __ISB __iar_builtin_ISB
#define __LDREXB __iar_builtin_LDREXB
#define __LDREXH __iar_builtin_LDREXH
#define __LDREXW __iar_builtin_LDREX
#define __RBIT __iar_builtin_RBIT
#define __REV __iar_builtin_REV
#define __REV16 __iar_builtin_REV16
__IAR_FT int16_t __REVSH(int16_t val)
{
return (int16_t) __iar_builtin_REVSH(val);
}
#define __ROR __iar_builtin_ROR
#define __RRX __iar_builtin_RRX
#define __SEV __iar_builtin_SEV
#define __SSAT __iar_builtin_SSAT
#define __STREXB __iar_builtin_STREXB
#define __STREXH __iar_builtin_STREXH
#define __STREXW __iar_builtin_STREX
#define __USAT __iar_builtin_USAT
#define __WFE __iar_builtin_WFE
#define __WFI __iar_builtin_WFI
#define __SADD8 __iar_builtin_SADD8
#define __QADD8 __iar_builtin_QADD8
#define __SHADD8 __iar_builtin_SHADD8
#define __UADD8 __iar_builtin_UADD8
#define __UQADD8 __iar_builtin_UQADD8
#define __UHADD8 __iar_builtin_UHADD8
#define __SSUB8 __iar_builtin_SSUB8
#define __QSUB8 __iar_builtin_QSUB8
#define __SHSUB8 __iar_builtin_SHSUB8
#define __USUB8 __iar_builtin_USUB8
#define __UQSUB8 __iar_builtin_UQSUB8
#define __UHSUB8 __iar_builtin_UHSUB8
#define __SADD16 __iar_builtin_SADD16
#define __QADD16 __iar_builtin_QADD16
#define __SHADD16 __iar_builtin_SHADD16
#define __UADD16 __iar_builtin_UADD16
#define __UQADD16 __iar_builtin_UQADD16
#define __UHADD16 __iar_builtin_UHADD16
#define __SSUB16 __iar_builtin_SSUB16
#define __QSUB16 __iar_builtin_QSUB16
#define __SHSUB16 __iar_builtin_SHSUB16
#define __USUB16 __iar_builtin_USUB16
#define __UQSUB16 __iar_builtin_UQSUB16
#define __UHSUB16 __iar_builtin_UHSUB16
#define __SASX __iar_builtin_SASX
#define __QASX __iar_builtin_QASX
#define __SHASX __iar_builtin_SHASX
#define __UASX __iar_builtin_UASX
#define __UQASX __iar_builtin_UQASX
#define __UHASX __iar_builtin_UHASX
#define __SSAX __iar_builtin_SSAX
#define __QSAX __iar_builtin_QSAX
#define __SHSAX __iar_builtin_SHSAX
#define __USAX __iar_builtin_USAX
#define __UQSAX __iar_builtin_UQSAX
#define __UHSAX __iar_builtin_UHSAX
#define __USAD8 __iar_builtin_USAD8
#define __USADA8 __iar_builtin_USADA8
#define __SSAT16 __iar_builtin_SSAT16
#define __USAT16 __iar_builtin_USAT16
#define __UXTB16 __iar_builtin_UXTB16
#define __UXTAB16 __iar_builtin_UXTAB16
#define __SXTB16 __iar_builtin_SXTB16
#define __SXTAB16 __iar_builtin_SXTAB16
#define __SMUAD __iar_builtin_SMUAD
#define __SMUADX __iar_builtin_SMUADX
#define __SMMLA __iar_builtin_SMMLA
#define __SMLAD __iar_builtin_SMLAD
#define __SMLADX __iar_builtin_SMLADX
#define __SMLALD __iar_builtin_SMLALD
#define __SMLALDX __iar_builtin_SMLALDX
#define __SMUSD __iar_builtin_SMUSD
#define __SMUSDX __iar_builtin_SMUSDX
#define __SMLSD __iar_builtin_SMLSD
#define __SMLSDX __iar_builtin_SMLSDX
#define __SMLSLD __iar_builtin_SMLSLD
#define __SMLSLDX __iar_builtin_SMLSLDX
#define __SEL __iar_builtin_SEL
#define __QADD __iar_builtin_QADD
#define __QSUB __iar_builtin_QSUB
#define __PKHBT __iar_builtin_PKHBT
#define __PKHTB __iar_builtin_PKHTB
#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */
#if !__FPU_PRESENT
#define __get_FPSCR __cmsis_iar_get_FPSR_not_active
#endif
#ifdef __INTRINSICS_INCLUDED
#error intrinsics.h is already included previously!
#endif
#include <intrinsics.h>
#if !__FPU_PRESENT
#define __get_FPSCR() (0)
#endif
#pragma diag_suppress=Pe940
#pragma diag_suppress=Pe177
#define __enable_irq __enable_interrupt
#define __disable_irq __disable_interrupt
#define __enable_fault_irq __enable_fiq
#define __disable_fault_irq __disable_fiq
#define __NOP __no_operation
#define __get_xPSR __get_PSR
__IAR_FT void __set_mode(uint32_t mode)
{
__ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory");
}
__IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr)
{
return __LDREX((unsigned long *)ptr);
}
__IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr)
{
return __STREX(value, (unsigned long *)ptr);
}
__IAR_FT uint32_t __RRX(uint32_t value)
{
uint32_t result;
__ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc");
return(result);
}
__IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2)
{
return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2));
}
__IAR_FT uint32_t __get_FPEXC(void)
{
#if (__FPU_PRESENT == 1)
uint32_t result;
__ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory");
return(result);
#else
return(0);
#endif
}
__IAR_FT void __set_FPEXC(uint32_t fpexc)
{
#if (__FPU_PRESENT == 1)
__ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory");
#endif
}
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) \
__ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" )
#define __set_CP(cp, op1, Rt, CRn, CRm, op2) \
__ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" )
#define __get_CP64(cp, op1, Rt, CRm) \
__ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" )
#define __set_CP64(cp, op1, Rt, CRm) \
__ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" )
#include "cmsis_cp15.h"
#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */
#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value))
__IAR_FT uint32_t __get_SP_usr(void)
{
uint32_t cpsr;
uint32_t result;
__ASM volatile(
"MRS %0, cpsr \n"
"CPS #0x1F \n" // no effect in USR mode
"MOV %1, sp \n"
"MSR cpsr_c, %2 \n" // no effect in USR mode
"ISB" : "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory"
);
return result;
}
__IAR_FT void __set_SP_usr(uint32_t topOfProcStack)
{
uint32_t cpsr;
__ASM volatile(
"MRS %0, cpsr \n"
"CPS #0x1F \n" // no effect in USR mode
"MOV sp, %1 \n"
"MSR cpsr_c, %2 \n" // no effect in USR mode
"ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory"
);
}
#define __get_mode() (__get_CPSR() & 0x1FU)
__STATIC_INLINE
void __FPU_Enable(void)
{
__ASM volatile(
//Permit access to VFP/NEON, registers by modifying CPACR
" MRC p15,0,R1,c1,c0,2 \n"
" ORR R1,R1,#0x00F00000 \n"
" MCR p15,0,R1,c1,c0,2 \n"
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
" ISB \n"
//Enable VFP/NEON
" VMRS R1,FPEXC \n"
" ORR R1,R1,#0x40000000 \n"
" VMSR FPEXC,R1 \n"
//Initialise VFP/NEON registers to 0
" MOV R2,#0 \n"
//Initialise D16 registers to 0
" VMOV D0, R2,R2 \n"
" VMOV D1, R2,R2 \n"
" VMOV D2, R2,R2 \n"
" VMOV D3, R2,R2 \n"
" VMOV D4, R2,R2 \n"
" VMOV D5, R2,R2 \n"
" VMOV D6, R2,R2 \n"
" VMOV D7, R2,R2 \n"
" VMOV D8, R2,R2 \n"
" VMOV D9, R2,R2 \n"
" VMOV D10,R2,R2 \n"
" VMOV D11,R2,R2 \n"
" VMOV D12,R2,R2 \n"
" VMOV D13,R2,R2 \n"
" VMOV D14,R2,R2 \n"
" VMOV D15,R2,R2 \n"
#ifdef __ARM_ADVANCED_SIMD__
//Initialise D32 registers to 0
" VMOV D16,R2,R2 \n"
" VMOV D17,R2,R2 \n"
" VMOV D18,R2,R2 \n"
" VMOV D19,R2,R2 \n"
" VMOV D20,R2,R2 \n"
" VMOV D21,R2,R2 \n"
" VMOV D22,R2,R2 \n"
" VMOV D23,R2,R2 \n"
" VMOV D24,R2,R2 \n"
" VMOV D25,R2,R2 \n"
" VMOV D26,R2,R2 \n"
" VMOV D27,R2,R2 \n"
" VMOV D28,R2,R2 \n"
" VMOV D29,R2,R2 \n"
" VMOV D30,R2,R2 \n"
" VMOV D31,R2,R2 \n"
#endif
//Initialise FPSCR to a known state
" VMRS R1,FPSCR \n"
" MOV32 R2,#0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
" AND R1,R1,R2 \n"
" VMSR FPSCR,R1 \n"
: : : "cc", "r1", "r2"
);
}
#undef __IAR_FT
#undef __ICCARM_V8
#pragma diag_default=Pe940
#pragma diag_default=Pe177
#endif /* __CMSIS_ICCARM_H__ */
@@ -0,0 +1,192 @@
/**************************************************************************//**
* @file irq_ctrl.h
* @brief Interrupt Controller API header file
* @version V1.1.0
* @date 03. March 2020
******************************************************************************/
/*
* Copyright (c) 2017-2020 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef IRQ_CTRL_H_
#define IRQ_CTRL_H_
#include <stdint.h>
#ifndef IRQHANDLER_T
#define IRQHANDLER_T
/// Interrupt handler data type
typedef void (*IRQHandler_t) (void);
#endif
#ifndef IRQN_ID_T
#define IRQN_ID_T
/// Interrupt ID number data type
typedef int32_t IRQn_ID_t;
#endif
/* Interrupt mode bit-masks */
#define IRQ_MODE_TRIG_Pos (0U)
#define IRQ_MODE_TRIG_Msk (0x07UL /*<< IRQ_MODE_TRIG_Pos*/)
#define IRQ_MODE_TRIG_LEVEL (0x00UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: level triggered interrupt
#define IRQ_MODE_TRIG_LEVEL_LOW (0x01UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: low level triggered interrupt
#define IRQ_MODE_TRIG_LEVEL_HIGH (0x02UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: high level triggered interrupt
#define IRQ_MODE_TRIG_EDGE (0x04UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: edge triggered interrupt
#define IRQ_MODE_TRIG_EDGE_RISING (0x05UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising edge triggered interrupt
#define IRQ_MODE_TRIG_EDGE_FALLING (0x06UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: falling edge triggered interrupt
#define IRQ_MODE_TRIG_EDGE_BOTH (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising and falling edge triggered interrupt
#define IRQ_MODE_TYPE_Pos (3U)
#define IRQ_MODE_TYPE_Msk (0x01UL << IRQ_MODE_TYPE_Pos)
#define IRQ_MODE_TYPE_IRQ (0x00UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU IRQ line
#define IRQ_MODE_TYPE_FIQ (0x01UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU FIQ line
#define IRQ_MODE_DOMAIN_Pos (4U)
#define IRQ_MODE_DOMAIN_Msk (0x01UL << IRQ_MODE_DOMAIN_Pos)
#define IRQ_MODE_DOMAIN_NONSECURE (0x00UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting non-secure domain
#define IRQ_MODE_DOMAIN_SECURE (0x01UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting secure domain
#define IRQ_MODE_CPU_Pos (5U)
#define IRQ_MODE_CPU_Msk (0xFFUL << IRQ_MODE_CPU_Pos)
#define IRQ_MODE_CPU_ALL (0x00UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets all CPUs
#define IRQ_MODE_CPU_0 (0x01UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 0
#define IRQ_MODE_CPU_1 (0x02UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 1
#define IRQ_MODE_CPU_2 (0x04UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 2
#define IRQ_MODE_CPU_3 (0x08UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 3
#define IRQ_MODE_CPU_4 (0x10UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 4
#define IRQ_MODE_CPU_5 (0x20UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 5
#define IRQ_MODE_CPU_6 (0x40UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 6
#define IRQ_MODE_CPU_7 (0x80UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 7
// Encoding in some early GIC implementations
#define IRQ_MODE_MODEL_Pos (13U)
#define IRQ_MODE_MODEL_Msk (0x1UL << IRQ_MODE_MODEL_Pos)
#define IRQ_MODE_MODEL_NN (0x0UL << IRQ_MODE_MODEL_Pos) ///< Corresponding interrupt is handled using the N-N model
#define IRQ_MODE_MODEL_1N (0x1UL << IRQ_MODE_MODEL_Pos) ///< Corresponding interrupt is handled using the 1-N model
#define IRQ_MODE_ERROR (0x80000000UL) ///< Bit indicating mode value error
/* Interrupt priority bit-masks */
#define IRQ_PRIORITY_Msk (0x0000FFFFUL) ///< Interrupt priority value bit-mask
#define IRQ_PRIORITY_ERROR (0x80000000UL) ///< Bit indicating priority value error
/// Initialize interrupt controller.
/// \return 0 on success, -1 on error.
int32_t IRQ_Initialize (void);
/// Register interrupt handler.
/// \param[in] irqn interrupt ID number
/// \param[in] handler interrupt handler function address
/// \return 0 on success, -1 on error.
int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler);
/// Get the registered interrupt handler.
/// \param[in] irqn interrupt ID number
/// \return registered interrupt handler function address.
IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn);
/// Enable interrupt.
/// \param[in] irqn interrupt ID number
/// \return 0 on success, -1 on error.
int32_t IRQ_Enable (IRQn_ID_t irqn);
/// Disable interrupt.
/// \param[in] irqn interrupt ID number
/// \return 0 on success, -1 on error.
int32_t IRQ_Disable (IRQn_ID_t irqn);
/// Get interrupt enable state.
/// \param[in] irqn interrupt ID number
/// \return 0 - interrupt is disabled, 1 - interrupt is enabled.
uint32_t IRQ_GetEnableState (IRQn_ID_t irqn);
/// Configure interrupt request mode.
/// \param[in] irqn interrupt ID number
/// \param[in] mode mode configuration
/// \return 0 on success, -1 on error.
int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode);
/// Get interrupt mode configuration.
/// \param[in] irqn interrupt ID number
/// \return current interrupt mode configuration with optional IRQ_MODE_ERROR bit set.
uint32_t IRQ_GetMode (IRQn_ID_t irqn);
/// Get ID number of current interrupt request (IRQ).
/// \return interrupt ID number.
IRQn_ID_t IRQ_GetActiveIRQ (void);
/// Get ID number of current fast interrupt request (FIQ).
/// \return interrupt ID number.
IRQn_ID_t IRQ_GetActiveFIQ (void);
/// Signal end of interrupt processing.
/// \param[in] irqn interrupt ID number
/// \return 0 on success, -1 on error.
int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn);
/// Set interrupt pending flag.
/// \param[in] irqn interrupt ID number
/// \return 0 on success, -1 on error.
int32_t IRQ_SetPending (IRQn_ID_t irqn);
/// Get interrupt pending flag.
/// \param[in] irqn interrupt ID number
/// \return 0 - interrupt is not pending, 1 - interrupt is pending.
uint32_t IRQ_GetPending (IRQn_ID_t irqn);
/// Clear interrupt pending flag.
/// \param[in] irqn interrupt ID number
/// \return 0 on success, -1 on error.
int32_t IRQ_ClearPending (IRQn_ID_t irqn);
/// Set interrupt priority value.
/// \param[in] irqn interrupt ID number
/// \param[in] priority interrupt priority value
/// \return 0 on success, -1 on error.
int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority);
/// Get interrupt priority.
/// \param[in] irqn interrupt ID number
/// \return current interrupt priority value with optional IRQ_PRIORITY_ERROR bit set.
uint32_t IRQ_GetPriority (IRQn_ID_t irqn);
/// Set priority masking threshold.
/// \param[in] priority priority masking threshold value
/// \return 0 on success, -1 on error.
int32_t IRQ_SetPriorityMask (uint32_t priority);
/// Get priority masking threshold
/// \return current priority masking threshold value with optional IRQ_PRIORITY_ERROR bit set.
uint32_t IRQ_GetPriorityMask (void);
/// Set priority grouping field split point
/// \param[in] bits number of MSB bits included in the group priority field comparison
/// \return 0 on success, -1 on error.
int32_t IRQ_SetPriorityGroupBits (uint32_t bits);
/// Get priority grouping field split point
/// \return current number of MSB bits included in the group priority field comparison with
/// optional IRQ_PRIORITY_ERROR bit set.
uint32_t IRQ_GetPriorityGroupBits (void);
#endif // IRQ_CTRL_H_
@@ -0,0 +1,414 @@
/*
* Copyright (c) 2016, 2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __ARM_COMPUTE_NEMATH_H__
#define __ARM_COMPUTE_NEMATH_H__
#if defined(ARM_MATH_NEON)
/** Calculate floor of a vector.
*
* @param[in] val Input vector value in F32 format.
*
* @return The calculated floor vector.
*/
static inline float32x4_t vfloorq_f32(float32x4_t val);
/** Calculate inverse square root.
*
* @param[in] x Input value.
*
* @return The calculated inverse square root.
*/
static inline float32x2_t vinvsqrt_f32(float32x2_t x);
/** Calculate inverse square root.
*
* @param[in] x Input value.
*
* @return The calculated inverse square root.
*/
static inline float32x4_t vinvsqrtq_f32(float32x4_t x);
/** Calculate reciprocal.
*
* @param[in] x Input value.
*
* @return The calculated reciprocal.
*/
static inline float32x2_t vinv_f32(float32x2_t x);
/** Calculate reciprocal.
*
* @param[in] x Input value.
*
* @return The calculated reciprocal.
*/
static inline float32x4_t vinvq_f32(float32x4_t x);
/** Perform a 7th degree polynomial approximation using Estrin's method.
*
* @param[in] x Input vector value in F32 format.
* @param[in] coeffs Polynomial coefficients table. (array of flattened float32x4_t vectors)
*
* @return The calculated approximation.
*/
static inline float32x4_t vtaylor_polyq_f32(float32x4_t x, const float32_t *coeffs);
/** Calculate exponential
*
* @param[in] x Input vector value in F32 format.
*
* @return The calculated exponent.
*/
static inline float32x4_t vexpq_f32(float32x4_t x);
/** Calculate logarithm
*
* @param[in] x Input vector value in F32 format.
*
* @return The calculated logarithm.
*/
static inline float32x4_t vlogq_f32(float32x4_t x);
/** Calculate hyperbolic tangent.
*
* tanh(x) = (e^2x - 1)/(e^2x + 1)
*
* @note We clamp x to [-5,5] to avoid overflowing issues.
*
* @param[in] val Input vector value in F32 format.
*
* @return The calculated Hyperbolic Tangent.
*/
static inline float32x4_t vtanhq_f32(float32x4_t val);
/** Calculate n power of a number.
*
* pow(x,n) = e^(n*log(x))
*
* @param[in] val Input vector value in F32 format.
* @param[in] n Powers to raise the input to.
*
* @return The calculated power.
*/
static inline float32x4_t vpowq_f32(float32x4_t val, float32x4_t n);
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
/** Calculate hyperbolic tangent.
*
* tanh(x) = (e^2x - 1)/(e^2x + 1)
*
* @note We clamp x to [-5,5] to avoid overflowing issues.
*
* @param[in] val Input vector value in F32 format.
*
* @return The calculated Hyperbolic Tangent.
*/
static inline float16x8_t vtanhq_f16(float16x8_t val);
/** Calculate reciprocal.
*
* @param[in] x Input value.
*
* @return The calculated reciprocal.
*/
static inline float16x4_t vinv_f16(float16x4_t x);
/** Calculate reciprocal.
*
* @param[in] x Input value.
*
* @return The calculated reciprocal.
*/
static inline float16x8_t vinvq_f16(float16x8_t x);
/** Calculate inverse square root.
*
* @param[in] x Input value.
*
* @return The calculated inverse square root.
*/
static inline float16x4_t vinvsqrt_f16(float16x4_t x);
/** Calculate inverse square root.
*
* @param[in] x Input value.
*
* @return The calculated inverse square root.
*/
static inline float16x8_t vinvsqrtq_f16(float16x8_t x);
/** Calculate exponential
*
* @param[in] x Input vector value in F16 format.
*
* @return The calculated exponent.
*/
static inline float16x8_t vexpq_f16(float16x8_t x);
/** Calculate n power of a number.
*
* pow(x,n) = e^(n*log(x))
*
* @param[in] val Input vector value in F16 format.
* @param[in] n Powers to raise the input to.
*
* @return The calculated power.
*/
static inline float16x8_t vpowq_f16(float16x8_t val, float16x8_t n);
#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
/** Exponent polynomial coefficients */
extern const float32_t exp_tab[4*8];
/** Logarithm polynomial coefficients */
extern const float32_t log_tab[4*8];
#ifndef DOXYGEN_SKIP_THIS
inline float32x4_t vfloorq_f32(float32x4_t val)
{
static const float32_t CONST_1[4] = {1.f,1.f,1.f,1.f};
const int32x4_t z = vcvtq_s32_f32(val);
const float32x4_t r = vcvtq_f32_s32(z);
return vbslq_f32(vcgtq_f32(r, val), vsubq_f32(r, vld1q_f32(CONST_1)), r);
}
inline float32x2_t vinvsqrt_f32(float32x2_t x)
{
float32x2_t sqrt_reciprocal = vrsqrte_f32(x);
sqrt_reciprocal = vmul_f32(vrsqrts_f32(vmul_f32(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
sqrt_reciprocal = vmul_f32(vrsqrts_f32(vmul_f32(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
return sqrt_reciprocal;
}
inline float32x4_t vinvsqrtq_f32(float32x4_t x)
{
float32x4_t sqrt_reciprocal = vrsqrteq_f32(x);
sqrt_reciprocal = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
sqrt_reciprocal = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
return sqrt_reciprocal;
}
inline float32x2_t vinv_f32(float32x2_t x)
{
float32x2_t recip = vrecpe_f32(x);
recip = vmul_f32(vrecps_f32(x, recip), recip);
recip = vmul_f32(vrecps_f32(x, recip), recip);
return recip;
}
inline float32x4_t vinvq_f32(float32x4_t x)
{
float32x4_t recip = vrecpeq_f32(x);
recip = vmulq_f32(vrecpsq_f32(x, recip), recip);
recip = vmulq_f32(vrecpsq_f32(x, recip), recip);
return recip;
}
inline float32x4_t vtaylor_polyq_f32(float32x4_t x, const float32_t *coeffs)
{
float32x4_t A = vmlaq_f32(vld1q_f32(&coeffs[4*0]), vld1q_f32(&coeffs[4*4]), x);
float32x4_t B = vmlaq_f32(vld1q_f32(&coeffs[4*2]), vld1q_f32(&coeffs[4*6]), x);
float32x4_t C = vmlaq_f32(vld1q_f32(&coeffs[4*1]), vld1q_f32(&coeffs[4*5]), x);
float32x4_t D = vmlaq_f32(vld1q_f32(&coeffs[4*3]), vld1q_f32(&coeffs[4*7]), x);
float32x4_t x2 = vmulq_f32(x, x);
float32x4_t x4 = vmulq_f32(x2, x2);
float32x4_t res = vmlaq_f32(vmlaq_f32(A, B, x2), vmlaq_f32(C, D, x2), x4);
return res;
}
inline float32x4_t vexpq_f32(float32x4_t x)
{
static const float32_t CONST_LN2[4] = {0.6931471805f,0.6931471805f,0.6931471805f,0.6931471805f}; // ln(2)
static const float32_t CONST_INV_LN2[4] = {1.4426950408f,1.4426950408f,1.4426950408f,1.4426950408f}; // 1/ln(2)
static const float32_t CONST_0[4] = {0.f,0.f,0.f,0.f};
static const int32_t CONST_NEGATIVE_126[4] = {-126,-126,-126,-126};
// Perform range reduction [-log(2),log(2)]
int32x4_t m = vcvtq_s32_f32(vmulq_f32(x, vld1q_f32(CONST_INV_LN2)));
float32x4_t val = vmlsq_f32(x, vcvtq_f32_s32(m), vld1q_f32(CONST_LN2));
// Polynomial Approximation
float32x4_t poly = vtaylor_polyq_f32(val, exp_tab);
// Reconstruct
poly = vreinterpretq_f32_s32(vqaddq_s32(vreinterpretq_s32_f32(poly), vqshlq_n_s32(m, 23)));
poly = vbslq_f32(vcltq_s32(m, vld1q_s32(CONST_NEGATIVE_126)), vld1q_f32(CONST_0), poly);
return poly;
}
inline float32x4_t vlogq_f32(float32x4_t x)
{
static const int32_t CONST_127[4] = {127,127,127,127}; // 127
static const float32_t CONST_LN2[4] = {0.6931471805f,0.6931471805f,0.6931471805f,0.6931471805f}; // ln(2)
// Extract exponent
int32x4_t m = vsubq_s32(vreinterpretq_s32_u32(vshrq_n_u32(vreinterpretq_u32_f32(x), 23)), vld1q_s32(CONST_127));
float32x4_t val = vreinterpretq_f32_s32(vsubq_s32(vreinterpretq_s32_f32(x), vshlq_n_s32(m, 23)));
// Polynomial Approximation
float32x4_t poly = vtaylor_polyq_f32(val, log_tab);
// Reconstruct
poly = vmlaq_f32(poly, vcvtq_f32_s32(m), vld1q_f32(CONST_LN2));
return poly;
}
inline float32x4_t vtanhq_f32(float32x4_t val)
{
static const float32_t CONST_1[4] = {1.f,1.f,1.f,1.f};
static const float32_t CONST_2[4] = {2.f,2.f,2.f,2.f};
static const float32_t CONST_MIN_TANH[4] = {-10.f,-10.f,-10.f,-10.f};
static const float32_t CONST_MAX_TANH[4] = {10.f,10.f,10.f,10.f};
float32x4_t x = vminq_f32(vmaxq_f32(val, vld1q_f32(CONST_MIN_TANH)), vld1q_f32(CONST_MAX_TANH));
float32x4_t exp2x = vexpq_f32(vmulq_f32(vld1q_f32(CONST_2), x));
float32x4_t num = vsubq_f32(exp2x, vld1q_f32(CONST_1));
float32x4_t den = vaddq_f32(exp2x, vld1q_f32(CONST_1));
float32x4_t tanh = vmulq_f32(num, vinvq_f32(den));
return tanh;
}
inline float32x4_t vpowq_f32(float32x4_t val, float32x4_t n)
{
return vexpq_f32(vmulq_f32(n, vlogq_f32(val)));
}
#endif /* DOXYGEN_SKIP_THIS */
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
/** Exponent polynomial coefficients */
/** Logarithm polynomial coefficients */
#ifndef DOXYGEN_SKIP_THIS
inline float16x8_t vfloorq_f16(float16x8_t val)
{
static const float16_t CONST_1[8] = {1.f,1.f,1.f,1.f,1.f,1.f,1.f,1.f};
const int16x8_t z = vcvtq_s16_f16(val);
const float16x8_t r = vcvtq_f16_s16(z);
return vbslq_f16(vcgtq_f16(r, val), vsubq_f16(r, vld1q_f16(CONST_1)), r);
}
inline float16x4_t vinvsqrt_f16(float16x4_t x)
{
float16x4_t sqrt_reciprocal = vrsqrte_f16(x);
sqrt_reciprocal = vmul_f16(vrsqrts_f16(vmul_f16(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
sqrt_reciprocal = vmul_f16(vrsqrts_f16(vmul_f16(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
return sqrt_reciprocal;
}
inline float16x8_t vinvsqrtq_f16(float16x8_t x)
{
float16x8_t sqrt_reciprocal = vrsqrteq_f16(x);
sqrt_reciprocal = vmulq_f16(vrsqrtsq_f16(vmulq_f16(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
sqrt_reciprocal = vmulq_f16(vrsqrtsq_f16(vmulq_f16(x, sqrt_reciprocal), sqrt_reciprocal), sqrt_reciprocal);
return sqrt_reciprocal;
}
inline float16x4_t vinv_f16(float16x4_t x)
{
float16x4_t recip = vrecpe_f16(x);
recip = vmul_f16(vrecps_f16(x, recip), recip);
recip = vmul_f16(vrecps_f16(x, recip), recip);
return recip;
}
inline float16x8_t vinvq_f16(float16x8_t x)
{
float16x8_t recip = vrecpeq_f16(x);
recip = vmulq_f16(vrecpsq_f16(x, recip), recip);
recip = vmulq_f16(vrecpsq_f16(x, recip), recip);
return recip;
}
inline float16x8_t vtanhq_f16(float16x8_t val)
{
const float16_t CONST_1[8] = {1.f,1.f,1.f,1.f,1.f,1.f,1.f,1.f};
const float16_t CONST_2[8] = {2.f,2.f,2.f,2.f,2.f,2.f,2.f,2.f};
const float16_t CONST_MIN_TANH[8] = {-10.f,-10.f,-10.f,-10.f,-10.f,-10.f,-10.f,-10.f};
const float16_t CONST_MAX_TANH[8] = {10.f,10.f,10.f,10.f,10.f,10.f,10.f,10.f};
const float16x8_t x = vminq_f16(vmaxq_f16(val, vld1q_f16(CONST_MIN_TANH)), vld1q_f16(CONST_MAX_TANH));
const float16x8_t exp2x = vexpq_f16(vmulq_f16(vld1q_f16(CONST_2), x));
const float16x8_t num = vsubq_f16(exp2x, vld1q_f16(CONST_1));
const float16x8_t den = vaddq_f16(exp2x, vld1q_f16(CONST_1));
const float16x8_t tanh = vmulq_f16(num, vinvq_f16(den));
return tanh;
}
inline float16x8_t vtaylor_polyq_f16(float16x8_t x, const float16_t *coeffs)
{
const float16x8_t A = vaddq_f16(vld1q_f16(&coeffs[8*0]), vmulq_f16(vld1q_f16(&coeffs[8*4]), x));
const float16x8_t B = vaddq_f16(vld1q_f16(&coeffs[8*2]), vmulq_f16(vld1q_f16(&coeffs[8*6]), x));
const float16x8_t C = vaddq_f16(vld1q_f16(&coeffs[8*1]), vmulq_f16(vld1q_f16(&coeffs[8*5]), x));
const float16x8_t D = vaddq_f16(vld1q_f16(&coeffs[8*3]), vmulq_f16(vld1q_f16(&coeffs[8*7]), x));
const float16x8_t x2 = vmulq_f16(x, x);
const float16x8_t x4 = vmulq_f16(x2, x2);
const float16x8_t res = vaddq_f16(vaddq_f16(A, vmulq_f16(B, x2)), vmulq_f16(vaddq_f16(C, vmulq_f16(D, x2)), x4));
return res;
}
inline float16x8_t vexpq_f16(float16x8_t x)
{
// TODO (COMPMID-1535) : Revisit FP16 approximations
const float32x4_t x_high = vcvt_f32_f16(vget_high_f16(x));
const float32x4_t x_low = vcvt_f32_f16(vget_low_f16(x));
const float16x8_t res = vcvt_high_f16_f32(vcvt_f16_f32(vexpq_f32(x_low)), vexpq_f32(x_high));
return res;
}
inline float16x8_t vlogq_f16(float16x8_t x)
{
// TODO (COMPMID-1535) : Revisit FP16 approximations
const float32x4_t x_high = vcvt_f32_f16(vget_high_f16(x));
const float32x4_t x_low = vcvt_f32_f16(vget_low_f16(x));
const float16x8_t res = vcvt_high_f16_f32(vcvt_f16_f32(vlogq_f32(x_low)), vlogq_f32(x_high));
return res;
}
inline float16x8_t vpowq_f16(float16x8_t val, float16x8_t n)
{
// TODO (giaiod01) - COMPMID-1535
float32x4_t n0_f32 = vcvt_f32_f16(vget_low_f16(n));
float32x4_t n1_f32 = vcvt_f32_f16(vget_high_f16(n));
float32x4_t val0_f32 = vcvt_f32_f16(vget_low_f16(val));
float32x4_t val1_f32 = vcvt_f32_f16(vget_high_f16(val));
float32x4_t res0_f32 = vexpq_f32(vmulq_f32(n0_f32, vlogq_f32(val0_f32)));
float32x4_t res1_f32 = vexpq_f32(vmulq_f32(n1_f32, vlogq_f32(val1_f32)));
return vcombine_f16(vcvt_f16_f32(res0_f32), vcvt_f16_f32(res1_f32));
}
#endif /* DOXYGEN_SKIP_THIS */
#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
#endif
#endif /* __ARM_COMPUTE_NEMATH_H__ */
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017-2019 ARM Software
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,19 @@
README
======
This folder is containing two files imported, and slightly modified, from the ComputeLibrary:
NEMath.h and arm_cl_tables.c
In the original compute library, there are instead two other files:
NEMath.h and NEMath.inl
NEMath.inl is included from NEMath.h whereas in this CMSIS DSP implementation, there is no NEMath.inl and its content is copied into NEMath.h
The tables contained in NEMath.inl have been moved to arm_cl_tables.c and finally the files are in C for the CMSIS DSP library and in C++ in the original Compute Library.
Otherwise, the features and implementations are the same : a few optimized Neon functions.
The license covering those files is different : It is a MIT license.
Other parts of the CMSIS-DSP are covered with an Apache-2.0 license.
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2016, 2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "arm_math.h"
#include "NEMath.h"
#if defined(ARM_MATH_NEON)
/** Exponent polynomial coefficients */
const float32_t exp_tab[4*8] =
{
1.f,1.f,1.f,1.f,
0.0416598916054f,0.0416598916054f,0.0416598916054f,0.0416598916054f,
0.500000596046f,0.500000596046f,0.500000596046f,0.500000596046f,
0.0014122662833f,0.0014122662833f,0.0014122662833f,0.0014122662833f,
1.00000011921f,1.00000011921f,1.00000011921f,1.00000011921f,
0.00833693705499f,0.00833693705499f,0.00833693705499f,0.00833693705499f,
0.166665703058f,0.166665703058f,0.166665703058f,0.166665703058f,
0.000195780929062f,0.000195780929062f,0.000195780929062f,0.000195780929062f
};
/** Logarithm polynomial coefficients */
const float32_t log_tab[4*8] =
{
-2.29561495781f,-2.29561495781f,-2.29561495781f,-2.29561495781f,
-2.47071170807f,-2.47071170807f,-2.47071170807f,-2.47071170807f,
-5.68692588806f,-5.68692588806f,-5.68692588806f,-5.68692588806f,
-0.165253549814f,-0.165253549814f,-0.165253549814f,-0.165253549814f,
5.17591238022f,5.17591238022f,5.17591238022f,5.17591238022f,
0.844007015228f,0.844007015228f,0.844007015228f,0.844007015228f,
4.58445882797f,4.58445882797f,4.58445882797f,4.58445882797f,
0.0141278216615f,0.0141278216615f,0.0141278216615f,0.0141278216615f
};
#endif
@@ -0,0 +1,539 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_common_tables.h
* Description: Extern declaration for common tables
*
* @version V1.10.0
* @date 08 July 2021
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARM_COMMON_TABLES_H
#define _ARM_COMMON_TABLES_H
#include "arm_math_types.h"
#include "dsp/fast_math_functions.h"
#ifdef __cplusplus
extern "C"
{
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
/* Double Precision Float CFFT twiddles */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREV_1024)
extern const uint16_t armBitRevTable[1024];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_16)
extern const uint64_t twiddleCoefF64_16[32];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_32)
extern const uint64_t twiddleCoefF64_32[64];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_64)
extern const uint64_t twiddleCoefF64_64[128];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_128)
extern const uint64_t twiddleCoefF64_128[256];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_256)
extern const uint64_t twiddleCoefF64_256[512];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_512)
extern const uint64_t twiddleCoefF64_512[1024];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_1024)
extern const uint64_t twiddleCoefF64_1024[2048];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_2048)
extern const uint64_t twiddleCoefF64_2048[4096];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_4096)
extern const uint64_t twiddleCoefF64_4096[8192];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_16)
extern const float32_t twiddleCoef_16[32];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_32)
extern const float32_t twiddleCoef_32[64];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_64)
extern const float32_t twiddleCoef_64[128];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_128)
extern const float32_t twiddleCoef_128[256];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_256)
extern const float32_t twiddleCoef_256[512];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_512)
extern const float32_t twiddleCoef_512[1024];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_1024)
extern const float32_t twiddleCoef_1024[2048];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_2048)
extern const float32_t twiddleCoef_2048[4096];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_4096)
extern const float32_t twiddleCoef_4096[8192];
#define twiddleCoef twiddleCoef_4096
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
/* Q31 */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_16)
extern const q31_t twiddleCoef_16_q31[24];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_32)
extern const q31_t twiddleCoef_32_q31[48];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_64)
extern const q31_t twiddleCoef_64_q31[96];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_128)
extern const q31_t twiddleCoef_128_q31[192];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_256)
extern const q31_t twiddleCoef_256_q31[384];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_512)
extern const q31_t twiddleCoef_512_q31[768];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_1024)
extern const q31_t twiddleCoef_1024_q31[1536];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_2048)
extern const q31_t twiddleCoef_2048_q31[3072];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_4096)
extern const q31_t twiddleCoef_4096_q31[6144];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_16)
extern const q15_t twiddleCoef_16_q15[24];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_32)
extern const q15_t twiddleCoef_32_q15[48];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_64)
extern const q15_t twiddleCoef_64_q15[96];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_128)
extern const q15_t twiddleCoef_128_q15[192];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_256)
extern const q15_t twiddleCoef_256_q15[384];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_512)
extern const q15_t twiddleCoef_512_q15[768];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_1024)
extern const q15_t twiddleCoef_1024_q15[1536];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_2048)
extern const q15_t twiddleCoef_2048_q15[3072];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_4096)
extern const q15_t twiddleCoef_4096_q15[6144];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
/* Double Precision Float RFFT twiddles */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_32)
extern const uint64_t twiddleCoefF64_rfft_32[32];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_64)
extern const uint64_t twiddleCoefF64_rfft_64[64];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_128)
extern const uint64_t twiddleCoefF64_rfft_128[128];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_256)
extern const uint64_t twiddleCoefF64_rfft_256[256];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_512)
extern const uint64_t twiddleCoefF64_rfft_512[512];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_1024)
extern const uint64_t twiddleCoefF64_rfft_1024[1024];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_2048)
extern const uint64_t twiddleCoefF64_rfft_2048[2048];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_4096)
extern const uint64_t twiddleCoefF64_rfft_4096[4096];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_32)
extern const float32_t twiddleCoef_rfft_32[32];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_64)
extern const float32_t twiddleCoef_rfft_64[64];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_128)
extern const float32_t twiddleCoef_rfft_128[128];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_256)
extern const float32_t twiddleCoef_rfft_256[256];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_512)
extern const float32_t twiddleCoef_rfft_512[512];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_1024)
extern const float32_t twiddleCoef_rfft_1024[1024];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_2048)
extern const float32_t twiddleCoef_rfft_2048[2048];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_4096)
extern const float32_t twiddleCoef_rfft_4096[4096];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
/* Double precision floating-point bit reversal tables */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_16)
#define ARMBITREVINDEXTABLEF64_16_TABLE_LENGTH ((uint16_t)12)
extern const uint16_t armBitRevIndexTableF64_16[ARMBITREVINDEXTABLEF64_16_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_32)
#define ARMBITREVINDEXTABLEF64_32_TABLE_LENGTH ((uint16_t)24)
extern const uint16_t armBitRevIndexTableF64_32[ARMBITREVINDEXTABLEF64_32_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_64)
#define ARMBITREVINDEXTABLEF64_64_TABLE_LENGTH ((uint16_t)56)
extern const uint16_t armBitRevIndexTableF64_64[ARMBITREVINDEXTABLEF64_64_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_128)
#define ARMBITREVINDEXTABLEF64_128_TABLE_LENGTH ((uint16_t)112)
extern const uint16_t armBitRevIndexTableF64_128[ARMBITREVINDEXTABLEF64_128_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_256)
#define ARMBITREVINDEXTABLEF64_256_TABLE_LENGTH ((uint16_t)240)
extern const uint16_t armBitRevIndexTableF64_256[ARMBITREVINDEXTABLEF64_256_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_512)
#define ARMBITREVINDEXTABLEF64_512_TABLE_LENGTH ((uint16_t)480)
extern const uint16_t armBitRevIndexTableF64_512[ARMBITREVINDEXTABLEF64_512_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_1024)
#define ARMBITREVINDEXTABLEF64_1024_TABLE_LENGTH ((uint16_t)992)
extern const uint16_t armBitRevIndexTableF64_1024[ARMBITREVINDEXTABLEF64_1024_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_2048)
#define ARMBITREVINDEXTABLEF64_2048_TABLE_LENGTH ((uint16_t)1984)
extern const uint16_t armBitRevIndexTableF64_2048[ARMBITREVINDEXTABLEF64_2048_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_4096)
#define ARMBITREVINDEXTABLEF64_4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t armBitRevIndexTableF64_4096[ARMBITREVINDEXTABLEF64_4096_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
/* floating-point bit reversal tables */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_16)
#define ARMBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20)
extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_32)
#define ARMBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48)
extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_64)
#define ARMBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56)
extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_128)
#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208)
extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_256)
#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440)
extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_512)
#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448)
extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_1024)
#define ARMBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800)
extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_2048)
#define ARMBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808)
extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_4096)
#define ARMBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
/* fixed-point bit reversal tables */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_16)
#define ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12)
extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_32)
#define ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24)
extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_64)
#define ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56)
extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_128)
#define ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112)
extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_256)
#define ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240)
extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_512)
#define ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480)
extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_1024)
#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992)
extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_2048)
#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_4096)
#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_F32)
extern const float32_t realCoefA[8192];
extern const float32_t realCoefB[8192];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q31)
extern const q31_t realCoefAQ31[8192];
extern const q31_t realCoefBQ31[8192];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q15)
extern const q15_t realCoefAQ15[8192];
extern const q15_t realCoefBQ15[8192];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_128)
extern const float32_t Weights_128[256];
extern const float32_t cos_factors_128[128];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_512)
extern const float32_t Weights_512[1024];
extern const float32_t cos_factors_512[512];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_2048)
extern const float32_t Weights_2048[4096];
extern const float32_t cos_factors_2048[2048];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_8192)
extern const float32_t Weights_8192[16384];
extern const float32_t cos_factors_8192[8192];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_128)
extern const q15_t WeightsQ15_128[256];
extern const q15_t cos_factorsQ15_128[128];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_512)
extern const q15_t WeightsQ15_512[1024];
extern const q15_t cos_factorsQ15_512[512];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_2048)
extern const q15_t WeightsQ15_2048[4096];
extern const q15_t cos_factorsQ15_2048[2048];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_8192)
extern const q15_t WeightsQ15_8192[16384];
extern const q15_t cos_factorsQ15_8192[8192];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_128)
extern const q31_t WeightsQ31_128[256];
extern const q31_t cos_factorsQ31_128[128];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_512)
extern const q31_t WeightsQ31_512[1024];
extern const q31_t cos_factorsQ31_512[512];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_2048)
extern const q31_t WeightsQ31_2048[4096];
extern const q31_t cos_factorsQ31_2048[2048];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_8192)
extern const q31_t WeightsQ31_8192[16384];
extern const q31_t cos_factorsQ31_8192[8192];
#endif
#endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_ALLOW_TABLES)
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q15)
extern const q15_t armRecipTableQ15[64];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q31)
extern const q31_t armRecipTableQ31[64];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
/* Tables for Fast Math Sine and Cosine */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_F32)
extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q31)
extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q15)
extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
/* Fast vector sqrt */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q31_MVE)
extern const q31_t sqrtTable_Q31[256];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
#endif
/* Accurate scalar sqrt */
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SQRT_Q31)
extern const q31_t sqrt_initial_lut_q31[32];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SQRT_Q15)
extern const q15_t sqrt_initial_lut_q15[16];
#endif
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q15_MVE)
extern const q15_t sqrtTable_Q15[256];
#endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */
#endif
#endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_TABLES) */
#if (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE)
extern const float32_t exp_tab[8];
extern const float32_t __logf_lut_f32[8];
#endif /* (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE) */
#if (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE)
extern const unsigned char hwLUT[256];
#endif /* (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) */
#ifdef __cplusplus
}
#endif
#endif /* ARM_COMMON_TABLES_H */
@@ -0,0 +1,86 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_const_structs.h
* Description: Constant structs that are initialized for user convenience.
* For example, some can be given as arguments to the arm_cfft_f32() function.
*
* @version V1.10.0
* @date 08 July 2021
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARM_CONST_STRUCTS_H
#define _ARM_CONST_STRUCTS_H
#include "arm_math_types.h"
#include "arm_common_tables.h"
#include "dsp/transform_functions.h"
#ifdef __cplusplus
extern "C"
{
#endif
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len16;
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len32;
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len64;
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len128;
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len256;
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len512;
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len1024;
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len2048;
extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len4096;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096;
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,753 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_helium_utils.h
* Description: Utility functions for Helium development
*
* @version V1.10.0
* @date 08 July 2021
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARM_UTILS_HELIUM_H_
#define _ARM_UTILS_HELIUM_H_
#ifdef __cplusplus
extern "C"
{
#endif
/***************************************
Definitions available for MVEF and MVEI
***************************************/
#if (defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEF) || defined(ARM_MATH_MVEI)) && !defined(ARM_MATH_AUTOVECTORIZE)
#define INACTIVELANE 0 /* inactive lane content */
#endif /* defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEF) || defined(ARM_MATH_MVEI) */
/***************************************
Definitions available for MVEF only
***************************************/
#if (defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEF)) && !defined(ARM_MATH_AUTOVECTORIZE)
__STATIC_FORCEINLINE float32_t vecAddAcrossF32Mve(float32x4_t in)
{
float32_t acc;
acc = vgetq_lane(in, 0) + vgetq_lane(in, 1) +
vgetq_lane(in, 2) + vgetq_lane(in, 3);
return acc;
}
/* newton initial guess */
#define INVSQRT_MAGIC_F32 0x5f3759df
#define INV_NEWTON_INIT_F32 0x7EF127EA
#define INVSQRT_NEWTON_MVE_F32(invSqrt, xHalf, xStart)\
{ \
float32x4_t tmp; \
\
/* tmp = xhalf * x * x */ \
tmp = vmulq(xStart, xStart); \
tmp = vmulq(tmp, xHalf); \
/* (1.5f - xhalf * x * x) */ \
tmp = vsubq(vdupq_n_f32(1.5f), tmp); \
/* x = x*(1.5f-xhalf*x*x); */ \
invSqrt = vmulq(tmp, xStart); \
}
#endif /* defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEF) */
/***************************************
Definitions available for f16 datatype with HW acceleration only
***************************************/
#if defined(ARM_FLOAT16_SUPPORTED)
#if defined (ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
__STATIC_FORCEINLINE float16_t vecAddAcrossF16Mve(float16x8_t in)
{
float16x8_t tmpVec;
_Float16 acc;
tmpVec = (float16x8_t) vrev32q_s16((int16x8_t) in);
in = vaddq_f16(tmpVec, in);
tmpVec = (float16x8_t) vrev64q_s32((int32x4_t) in);
in = vaddq_f16(tmpVec, in);
acc = (_Float16)vgetq_lane_f16(in, 0) + (_Float16)vgetq_lane_f16(in, 4);
return acc;
}
__STATIC_FORCEINLINE float16x8_t __mve_cmplx_sum_intra_vec_f16(
float16x8_t vecIn)
{
float16x8_t vecTmp, vecOut;
uint32_t tmp;
vecTmp = (float16x8_t) vrev64q_s32((int32x4_t) vecIn);
// TO TRACK : using canonical addition leads to unefficient code generation for f16
// vecTmp = vecTmp + vecAccCpx0;
/*
* Compute
* re0+re1 | im0+im1 | re0+re1 | im0+im1
* re2+re3 | im2+im3 | re2+re3 | im2+im3
*/
vecTmp = vaddq_f16(vecTmp, vecIn);
vecOut = vecTmp;
/*
* shift left, random tmp insertion in bottom
*/
vecOut = vreinterpretq_f16_s32(vshlcq_s32(vreinterpretq_s32_f16(vecOut) , &tmp, 32));
/*
* Compute:
* DONTCARE | DONTCARE | re0+re1+re0+re1 |im0+im1+im0+im1
* re0+re1+re2+re3 | im0+im1+im2+im3 | re2+re3+re2+re3 |im2+im3+im2+im3
*/
vecOut = vaddq_f16(vecOut, vecTmp);
/*
* Cmplx sum is in 4rd & 5th f16 elt
* return full vector
*/
return vecOut;
}
#define mve_cmplx_sum_intra_r_i_f16(vec, Re, Im) \
{ \
float16x8_t vecOut = __mve_cmplx_sum_intra_vec_f16(vec); \
Re = vgetq_lane(vecOut, 4); \
Im = vgetq_lane(vecOut, 5); \
}
__STATIC_FORCEINLINE void mve_cmplx_sum_intra_vec_f16(
float16x8_t vecIn,
float16_t *pOut)
{
float16x8_t vecOut = __mve_cmplx_sum_intra_vec_f16(vecIn);
/*
* Cmplx sum is in 4rd & 5th f16 elt
* use 32-bit extraction
*/
*(float32_t *) pOut = ((float32x4_t) vecOut)[2];
}
#define INVSQRT_MAGIC_F16 0x59ba /* ( 0x1ba = 0x3759df >> 13) */
/* canonical version of INVSQRT_NEWTON_MVE_F16 leads to bad performance */
#define INVSQRT_NEWTON_MVE_F16(invSqrt, xHalf, xStart) \
{ \
float16x8_t tmp; \
\
/* tmp = xhalf * x * x */ \
tmp = vmulq(xStart, xStart); \
tmp = vmulq(tmp, xHalf); \
/* (1.5f - xhalf * x * x) */ \
tmp = vsubq(vdupq_n_f16((float16_t)1.5), tmp); \
/* x = x*(1.5f-xhalf*x*x); */ \
invSqrt = vmulq(tmp, xStart); \
}
#endif
#endif
/***************************************
Definitions available for MVEI and MVEF only
***************************************/
#if (defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEF) || defined(ARM_MATH_MVEI)) && !defined(ARM_MATH_AUTOVECTORIZE)
/* Following functions are used to transpose matrix in f32 and q31 cases */
__STATIC_INLINE arm_status arm_mat_trans_32bit_2x2_mve(
uint32_t * pDataSrc,
uint32_t * pDataDest)
{
static const uint32x4_t vecOffs = { 0, 2, 1, 3 };
/*
*
* | 0 1 | => | 0 2 |
* | 2 3 | | 1 3 |
*
*/
uint32x4_t vecIn = vldrwq_u32((uint32_t const *)pDataSrc);
vstrwq_scatter_shifted_offset_u32(pDataDest, vecOffs, vecIn);
return (ARM_MATH_SUCCESS);
}
__STATIC_INLINE arm_status arm_mat_trans_32bit_3x3_mve(
uint32_t * pDataSrc,
uint32_t * pDataDest)
{
const uint32x4_t vecOffs1 = { 0, 3, 6, 1};
const uint32x4_t vecOffs2 = { 4, 7, 2, 5};
/*
*
* | 0 1 2 | | 0 3 6 | 4 x 32 flattened version | 0 3 6 1 |
* | 3 4 5 | => | 1 4 7 | => | 4 7 2 5 |
* | 6 7 8 | | 2 5 8 | (row major) | 8 . . . |
*
*/
uint32x4_t vecIn1 = vldrwq_u32((uint32_t const *) pDataSrc);
uint32x4_t vecIn2 = vldrwq_u32((uint32_t const *) &pDataSrc[4]);
vstrwq_scatter_shifted_offset_u32(pDataDest, vecOffs1, vecIn1);
vstrwq_scatter_shifted_offset_u32(pDataDest, vecOffs2, vecIn2);
pDataDest[8] = pDataSrc[8];
return (ARM_MATH_SUCCESS);
}
__STATIC_INLINE arm_status arm_mat_trans_32bit_4x4_mve(uint32_t * pDataSrc, uint32_t * pDataDest)
{
/*
* 4x4 Matrix transposition
* is 4 x de-interleave operation
*
* 0 1 2 3 0 4 8 12
* 4 5 6 7 1 5 9 13
* 8 9 10 11 2 6 10 14
* 12 13 14 15 3 7 11 15
*/
uint32x4x4_t vecIn;
vecIn = vld4q((uint32_t const *) pDataSrc);
vstrwq(pDataDest, vecIn.val[0]);
pDataDest += 4;
vstrwq(pDataDest, vecIn.val[1]);
pDataDest += 4;
vstrwq(pDataDest, vecIn.val[2]);
pDataDest += 4;
vstrwq(pDataDest, vecIn.val[3]);
return (ARM_MATH_SUCCESS);
}
__STATIC_INLINE arm_status arm_mat_trans_32bit_generic_mve(
uint16_t srcRows,
uint16_t srcCols,
uint32_t * pDataSrc,
uint32_t * pDataDest)
{
uint32x4_t vecOffs;
uint32_t i;
uint32_t blkCnt;
uint32_t const *pDataC;
uint32_t *pDataDestR;
uint32x4_t vecIn;
vecOffs = vidupq_u32((uint32_t)0, 1);
vecOffs = vecOffs * srcCols;
i = srcCols;
do
{
pDataC = (uint32_t const *) pDataSrc;
pDataDestR = pDataDest;
blkCnt = srcRows >> 2;
while (blkCnt > 0U)
{
vecIn = vldrwq_gather_shifted_offset_u32(pDataC, vecOffs);
vstrwq(pDataDestR, vecIn);
pDataDestR += 4;
pDataC = pDataC + srcCols * 4;
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
}
/*
* tail
*/
blkCnt = srcRows & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecIn = vldrwq_gather_shifted_offset_u32(pDataC, vecOffs);
vstrwq_p(pDataDestR, vecIn, p0);
}
pDataSrc += 1;
pDataDest += srcRows;
}
while (--i);
return (ARM_MATH_SUCCESS);
}
__STATIC_INLINE arm_status arm_mat_cmplx_trans_32bit(
uint16_t srcRows,
uint16_t srcCols,
uint32_t *pDataSrc,
uint16_t dstRows,
uint16_t dstCols,
uint32_t *pDataDest)
{
uint32_t i;
uint32_t const *pDataC;
uint32_t *pDataRow;
uint32_t *pDataDestR, *pDataDestRow;
uint32x4_t vecOffsRef, vecOffsCur;
uint32_t blkCnt;
uint32x4_t vecIn;
#ifdef ARM_MATH_MATRIX_CHECK
/*
* Check for matrix mismatch condition
*/
if ((srcRows != dstCols) || (srcCols != dstRows))
{
/*
* Set status as ARM_MATH_SIZE_MISMATCH
*/
return ARM_MATH_SIZE_MISMATCH;
}
#else
(void)dstRows;
(void)dstCols;
#endif
/* 2x2, 3x3 and 4x4 specialization to be added */
vecOffsRef[0] = 0;
vecOffsRef[1] = 1;
vecOffsRef[2] = srcCols << 1;
vecOffsRef[3] = (srcCols << 1) + 1;
pDataRow = pDataSrc;
pDataDestRow = pDataDest;
i = srcCols;
do
{
pDataC = (uint32_t const *) pDataRow;
pDataDestR = pDataDestRow;
vecOffsCur = vecOffsRef;
blkCnt = (srcRows * CMPLX_DIM) >> 2;
while (blkCnt > 0U)
{
vecIn = vldrwq_gather_shifted_offset(pDataC, vecOffsCur);
vstrwq(pDataDestR, vecIn);
pDataDestR += 4;
vecOffsCur = vaddq(vecOffsCur, (srcCols << 2));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
}
/*
* tail
* (will be merged thru tail predication)
*/
blkCnt = (srcRows * CMPLX_DIM) & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecIn = vldrwq_gather_shifted_offset(pDataC, vecOffsCur);
vstrwq_p(pDataDestR, vecIn, p0);
}
pDataRow += CMPLX_DIM;
pDataDestRow += (srcRows * CMPLX_DIM);
}
while (--i);
return (ARM_MATH_SUCCESS);
}
__STATIC_INLINE arm_status arm_mat_trans_16bit_2x2(uint16_t * pDataSrc, uint16_t * pDataDest)
{
pDataDest[0] = pDataSrc[0];
pDataDest[3] = pDataSrc[3];
pDataDest[2] = pDataSrc[1];
pDataDest[1] = pDataSrc[2];
return (ARM_MATH_SUCCESS);
}
__STATIC_INLINE arm_status arm_mat_trans_16bit_3x3_mve(uint16_t * pDataSrc, uint16_t * pDataDest)
{
static const uint16_t stridesTr33[8] = { 0, 3, 6, 1, 4, 7, 2, 5 };
uint16x8_t vecOffs1;
uint16x8_t vecIn1;
/*
*
* | 0 1 2 | | 0 3 6 | 8 x 16 flattened version | 0 3 6 1 4 7 2 5 |
* | 3 4 5 | => | 1 4 7 | => | 8 . . . . . . . |
* | 6 7 8 | | 2 5 8 | (row major)
*
*/
vecOffs1 = vldrhq_u16((uint16_t const *) stridesTr33);
vecIn1 = vldrhq_u16((uint16_t const *) pDataSrc);
vstrhq_scatter_shifted_offset_u16(pDataDest, vecOffs1, vecIn1);
pDataDest[8] = pDataSrc[8];
return (ARM_MATH_SUCCESS);
}
__STATIC_INLINE arm_status arm_mat_trans_16bit_4x4_mve(uint16_t * pDataSrc, uint16_t * pDataDest)
{
static const uint16_t stridesTr44_1[8] = { 0, 4, 8, 12, 1, 5, 9, 13 };
static const uint16_t stridesTr44_2[8] = { 2, 6, 10, 14, 3, 7, 11, 15 };
uint16x8_t vecOffs1, vecOffs2;
uint16x8_t vecIn1, vecIn2;
uint16_t const * pDataSrcVec = (uint16_t const *) pDataSrc;
/*
* 4x4 Matrix transposition
*
* | 0 1 2 3 | | 0 4 8 12 | 8 x 16 flattened version
* | 4 5 6 7 | => | 1 5 9 13 | => [0 4 8 12 1 5 9 13]
* | 8 9 10 11 | | 2 6 10 14 | [2 6 10 14 3 7 11 15]
* | 12 13 14 15 | | 3 7 11 15 |
*/
vecOffs1 = vldrhq_u16((uint16_t const *) stridesTr44_1);
vecOffs2 = vldrhq_u16((uint16_t const *) stridesTr44_2);
vecIn1 = vldrhq_u16(pDataSrcVec);
pDataSrcVec += 8;
vecIn2 = vldrhq_u16(pDataSrcVec);
vstrhq_scatter_shifted_offset_u16(pDataDest, vecOffs1, vecIn1);
vstrhq_scatter_shifted_offset_u16(pDataDest, vecOffs2, vecIn2);
return (ARM_MATH_SUCCESS);
}
__STATIC_INLINE arm_status arm_mat_trans_16bit_generic(
uint16_t srcRows,
uint16_t srcCols,
uint16_t * pDataSrc,
uint16_t * pDataDest)
{
uint16x8_t vecOffs;
uint32_t i;
uint32_t blkCnt;
uint16_t const *pDataC;
uint16_t *pDataDestR;
uint16x8_t vecIn;
vecOffs = vidupq_u16((uint32_t)0, 1);
vecOffs = vecOffs * srcCols;
i = srcCols;
while(i > 0U)
{
pDataC = (uint16_t const *) pDataSrc;
pDataDestR = pDataDest;
blkCnt = srcRows >> 3;
while (blkCnt > 0U)
{
vecIn = vldrhq_gather_shifted_offset_u16(pDataC, vecOffs);
vstrhq_u16(pDataDestR, vecIn);
pDataDestR += 8;
pDataC = pDataC + srcCols * 8;
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
}
/*
* tail
*/
blkCnt = srcRows & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecIn = vldrhq_gather_shifted_offset_u16(pDataC, vecOffs);
vstrhq_p_u16(pDataDestR, vecIn, p0);
}
pDataSrc += 1;
pDataDest += srcRows;
i--;
}
return (ARM_MATH_SUCCESS);
}
__STATIC_INLINE arm_status arm_mat_cmplx_trans_16bit(
uint16_t srcRows,
uint16_t srcCols,
uint16_t *pDataSrc,
uint16_t dstRows,
uint16_t dstCols,
uint16_t *pDataDest)
{
static const uint16_t loadCmplxCol[8] = { 0, 0, 1, 1, 2, 2, 3, 3 };
int i;
uint16x8_t vecOffsRef, vecOffsCur;
uint16_t const *pDataC;
uint16_t *pDataRow;
uint16_t *pDataDestR, *pDataDestRow;
uint32_t blkCnt;
uint16x8_t vecIn;
#ifdef ARM_MATH_MATRIX_CHECK
/*
* Check for matrix mismatch condition
*/
if ((srcRows != dstCols) || (srcCols != dstRows))
{
/*
* Set status as ARM_MATH_SIZE_MISMATCH
*/
return ARM_MATH_SIZE_MISMATCH;
}
#else
(void)dstRows;
(void)dstCols;
#endif
/*
* 2x2, 3x3 and 4x4 specialization to be added
*/
/*
* build [0, 1, 2xcol, 2xcol+1, 4xcol, 4xcol+1, 6xcol, 6xcol+1]
*/
vecOffsRef = vldrhq_u16((uint16_t const *) loadCmplxCol);
vecOffsRef = vmulq(vecOffsRef, (uint16_t) (srcCols * CMPLX_DIM))
+ viwdupq_u16((uint32_t)0, (uint16_t) 2, 1);
pDataRow = pDataSrc;
pDataDestRow = pDataDest;
i = srcCols;
do
{
pDataC = (uint16_t const *) pDataRow;
pDataDestR = pDataDestRow;
vecOffsCur = vecOffsRef;
blkCnt = (srcRows * CMPLX_DIM) >> 3;
while (blkCnt > 0U)
{
vecIn = vldrhq_gather_shifted_offset(pDataC, vecOffsCur);
vstrhq(pDataDestR, vecIn);
pDataDestR+= 8; // VEC_LANES_U16
vecOffsCur = vaddq(vecOffsCur, (srcCols << 3));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
}
/*
* tail
* (will be merged thru tail predication)
*/
blkCnt = (srcRows * CMPLX_DIM) & 0x7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecIn = vldrhq_gather_shifted_offset(pDataC, vecOffsCur);
vstrhq_p(pDataDestR, vecIn, p0);
}
pDataRow += CMPLX_DIM;
pDataDestRow += (srcRows * CMPLX_DIM);
}
while (--i);
return (ARM_MATH_SUCCESS);
}
#endif /* MVEF and MVEI */
/***************************************
Definitions available for MVEI only
***************************************/
#if (defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEI)) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_common_tables.h"
#define MVE_ASRL_SAT16(acc, shift) ((sqrshrl_sat48(acc, -(32-shift)) >> 32) & 0xffffffff)
#define MVE_ASRL_SAT32(acc, shift) ((sqrshrl(acc, -(32-shift)) >> 32) & 0xffffffff)
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q31_MVE)
__STATIC_INLINE q31x4_t FAST_VSQRT_Q31(q31x4_t vecIn)
{
q63x2_t vecTmpLL;
q31x4_t vecTmp0, vecTmp1;
q31_t scale;
q63_t tmp64;
q31x4_t vecNrm, vecDst, vecIdx, vecSignBits;
vecSignBits = vclsq(vecIn);
vecSignBits = vbicq_n_s32(vecSignBits, 1);
/*
* in = in << no_of_sign_bits;
*/
vecNrm = vshlq(vecIn, vecSignBits);
/*
* index = in >> 24;
*/
vecIdx = vecNrm >> 24;
vecIdx = vecIdx << 1;
vecTmp0 = vldrwq_gather_shifted_offset_s32(sqrtTable_Q31, (uint32x4_t)vecIdx);
vecIdx = vecIdx + 1;
vecTmp1 = vldrwq_gather_shifted_offset_s32(sqrtTable_Q31, (uint32x4_t)vecIdx);
vecTmp1 = vqrdmulhq(vecTmp1, vecNrm);
vecTmp0 = vecTmp0 - vecTmp1;
vecTmp1 = vqrdmulhq(vecTmp0, vecTmp0);
vecTmp1 = vqrdmulhq(vecNrm, vecTmp1);
vecTmp1 = vdupq_n_s32(0x18000000) - vecTmp1;
vecTmp0 = vqrdmulhq(vecTmp0, vecTmp1);
vecTmpLL = vmullbq_int(vecNrm, vecTmp0);
/*
* scale elements 0, 2
*/
scale = 26 + (vecSignBits[0] >> 1);
tmp64 = asrl(vecTmpLL[0], scale);
vecDst[0] = (q31_t) tmp64;
scale = 26 + (vecSignBits[2] >> 1);
tmp64 = asrl(vecTmpLL[1], scale);
vecDst[2] = (q31_t) tmp64;
vecTmpLL = vmulltq_int(vecNrm, vecTmp0);
/*
* scale elements 1, 3
*/
scale = 26 + (vecSignBits[1] >> 1);
tmp64 = asrl(vecTmpLL[0], scale);
vecDst[1] = (q31_t) tmp64;
scale = 26 + (vecSignBits[3] >> 1);
tmp64 = asrl(vecTmpLL[1], scale);
vecDst[3] = (q31_t) tmp64;
/*
* set negative values to 0
*/
vecDst = vdupq_m(vecDst, 0, vcmpltq_n_s32(vecIn, 0));
return vecDst;
}
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q15_MVE)
__STATIC_INLINE q15x8_t FAST_VSQRT_Q15(q15x8_t vecIn)
{
q31x4_t vecTmpLev, vecTmpLodd, vecSignL;
q15x8_t vecTmp0, vecTmp1;
q15x8_t vecNrm, vecDst, vecIdx, vecSignBits;
vecDst = vuninitializedq_s16();
vecSignBits = vclsq(vecIn);
vecSignBits = vbicq_n_s16(vecSignBits, 1);
/*
* in = in << no_of_sign_bits;
*/
vecNrm = vshlq(vecIn, vecSignBits);
vecIdx = vecNrm >> 8;
vecIdx = vecIdx << 1;
vecTmp0 = vldrhq_gather_shifted_offset_s16(sqrtTable_Q15, (uint16x8_t)vecIdx);
vecIdx = vecIdx + 1;
vecTmp1 = vldrhq_gather_shifted_offset_s16(sqrtTable_Q15, (uint16x8_t)vecIdx);
vecTmp1 = vqrdmulhq(vecTmp1, vecNrm);
vecTmp0 = vecTmp0 - vecTmp1;
vecTmp1 = vqrdmulhq(vecTmp0, vecTmp0);
vecTmp1 = vqrdmulhq(vecNrm, vecTmp1);
vecTmp1 = vdupq_n_s16(0x1800) - vecTmp1;
vecTmp0 = vqrdmulhq(vecTmp0, vecTmp1);
vecSignBits = vecSignBits >> 1;
vecTmpLev = vmullbq_int(vecNrm, vecTmp0);
vecTmpLodd = vmulltq_int(vecNrm, vecTmp0);
vecTmp0 = vecSignBits + 10;
/*
* negate sign to apply register based vshl
*/
vecTmp0 = -vecTmp0;
/*
* shift even elements
*/
vecSignL = vmovlbq(vecTmp0);
vecTmpLev = vshlq(vecTmpLev, vecSignL);
/*
* shift odd elements
*/
vecSignL = vmovltq(vecTmp0);
vecTmpLodd = vshlq(vecTmpLodd, vecSignL);
/*
* merge and narrow odd and even parts
*/
vecDst = vmovnbq_s32(vecDst, vecTmpLev);
vecDst = vmovntq_s32(vecDst, vecTmpLodd);
/*
* set negative values to 0
*/
vecDst = vdupq_m(vecDst, 0, vcmpltq_n_s16(vecIn, 0));
return vecDst;
}
#endif
#endif /* defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEI) */
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,236 @@
/******************************************************************************
* @file arm_math.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2021 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
\mainpage CMSIS DSP Software Library
*
* \section intro Introduction
*
* This user manual describes the CMSIS DSP software library,
* a suite of common signal processing functions for use on Cortex-M and Cortex-A processor
* based devices.
*
* The library is divided into a number of functions each covering a specific category:
* - Basic math functions
* - Fast math functions
* - Complex math functions
* - Filtering functions
* - Matrix functions
* - Transform functions
* - Motor control functions
* - Statistical functions
* - Support functions
* - Interpolation functions
* - Support Vector Machine functions (SVM)
* - Bayes classifier functions
* - Distance functions
* - Quaternion functions
*
* The library has generally separate functions for operating on 8-bit integers, 16-bit integers,
* 32-bit integer and 32-bit floating-point values.
*
* The library is providing vectorized versions of most algorthms for Helium
* and of most f32 algorithms for Neon.
*
* When using a vectorized version, provide a little bit of padding after the end of
* a buffer (3 words) because the vectorized code may read a little bit after the end
* of a buffer. You don't have to modify your buffers but just ensure that the
* end of buffer + padding is not outside of a memory region.
*
* \section using Using the Library
*
* The library is released in source form. It is strongly advised to compile the library using -Ofast to
* have the best performances.
*
* The library functions are declared in the public file <code>arm_math.h</code> which is placed in the <code>Include</code> folder.
* Simply include this file. If you don't want to include everything, you can also rely
* on headers in Include/dsp folder and use only what you need.
*
* \section example Examples
*
* The library ships with a number of examples which demonstrate how to use the library functions.
*
* \section toolchain Toolchain Support
*
* The library is now tested on Fast Models building with cmake.
* Core M0, M4, M7, M33, M55, A32 are tested.
*
*
* \section preprocessor Preprocessor Macros
*
* Each library project have different preprocessor macros.
*
* - ARM_MATH_BIG_ENDIAN:
*
* Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets.
*
* - ARM_MATH_MATRIX_CHECK:
*
* Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices
*
* - ARM_MATH_ROUNDING:
*
* Define macro ARM_MATH_ROUNDING for rounding on support functions
*
* - ARM_MATH_LOOPUNROLL:
*
* Define macro ARM_MATH_LOOPUNROLL to enable manual loop unrolling in DSP functions
*
* - ARM_MATH_NEON:
*
* Define macro ARM_MATH_NEON to enable Neon versions of the DSP functions.
* It is not enabled by default when Neon is available because performances are
* dependent on the compiler and target architecture.
*
* - ARM_MATH_NEON_EXPERIMENTAL:
*
* Define macro ARM_MATH_NEON_EXPERIMENTAL to enable experimental Neon versions of
* of some DSP functions. Experimental Neon versions currently do not have better
* performances than the scalar versions.
*
* - ARM_MATH_HELIUM:
*
* It implies the flags ARM_MATH_MVEF and ARM_MATH_MVEI and ARM_MATH_MVE_FLOAT16.
*
* - ARM_MATH_HELIUM_EXPERIMENTAL:
*
* Only taken into account when ARM_MATH_MVEF, ARM_MATH_MVEI or ARM_MATH_MVE_FLOAT16 are defined.
* Enable some vector versions which may have worse performance than scalar
* depending on the core / compiler configuration.
*
* - ARM_MATH_MVEF:
*
* Select Helium versions of the f32 algorithms.
* It implies ARM_MATH_FLOAT16 and ARM_MATH_MVEI.
*
* - ARM_MATH_MVEI:
*
* Select Helium versions of the int and fixed point algorithms.
*
* - ARM_MATH_MVE_FLOAT16:
*
* MVE Float16 implementations of some algorithms (Requires MVE extension).
*
* - DISABLEFLOAT16:
*
* Disable float16 algorithms when __fp16 is not supported for a
* specific compiler / core configuration.
* This is only valid for scalar. When vector architecture is
* supporting f16 then it can't be disabled.
*
* - ARM_MATH_AUTOVECTORIZE:
*
* With Helium or Neon, disable the use of vectorized code with C intrinsics
* and use pure C instead. The vectorization is then done by the compiler.
*
* <hr>
* \section pack CMSIS-DSP in ARM::CMSIS Pack
*
* The following files relevant to CMSIS-DSP are present in the <b>ARM::CMSIS</b> Pack directories:
* |File/Folder |Content |
* |---------------------------------|------------------------------------------------------------------------|
* |\b CMSIS\\Documentation\\DSP | This documentation |
* |\b CMSIS\\DSP\\Examples | Example projects demonstrating the usage of the library functions |
* |\b CMSIS\\DSP\\Include | DSP_Lib include files for using and building the lib
* |\b CMSIS\\DSP\\PrivateInclude | DSP_Lib private include files for building the lib |
* |\b CMSIS\\DSP\\Lib | DSP_Lib binaries |
* |\b CMSIS\\DSP\\Source | DSP_Lib source files |
*
* <hr>
* \section rev Revision History of CMSIS-DSP
* Please refer to \ref ChangeLog_pg.
*/
/**
* @defgroup groupExamples Examples
*/
#ifndef _ARM_MATH_H
#define _ARM_MATH_H
#include "arm_math_types.h"
#include "arm_math_memory.h"
#include "dsp/none.h"
#include "dsp/utils.h"
#include "dsp/basic_math_functions.h"
#include "dsp/interpolation_functions.h"
//#include "dsp/bayes_functions.h" // eliminate by Gatsby 2022-10-13
#include "dsp/matrix_functions.h"
#include "dsp/complex_math_functions.h"
#include "dsp/statistics_functions.h"
//#include "dsp/controller_functions.h" // eliminate by Gatsby 2022-10-13
#include "dsp/support_functions.h"
#include "dsp/distance_functions.h"
//#include "dsp/svm_functions.h" // eliminate by Gatsby 2022-10-13
#include "dsp/fast_math_functions.h"
#include "dsp/transform_functions.h"
#include "dsp/filtering_functions.h"
//#include "dsp/quaternion_math_functions.h" // eliminate by Gatsby 2022-10-13
#ifdef __cplusplus
extern "C"
{
#endif
//#define TABLE_SPACING_Q31 0x400000
//#define TABLE_SPACING_Q15 0x80
#ifdef __cplusplus
}
#endif
#endif /* _ARM_MATH_H */
/**
*
* End of file.
*/
@@ -0,0 +1,206 @@
/******************************************************************************
* @file arm_math_memory.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2021 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARM_MATH_MEMORY_H_
#define _ARM_MATH_MEMORY_H_
#include "arm_math_types.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
@brief definition to read/write two 16 bit values.
@deprecated
*/
#if defined ( __CC_ARM )
#define __SIMD32_TYPE int32_t __packed
#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 )
#define __SIMD32_TYPE int32_t
#elif defined ( __GNUC__ )
#define __SIMD32_TYPE int32_t
#elif defined ( __ICCARM__ )
#define __SIMD32_TYPE int32_t __packed
#elif defined ( __TI_ARM__ )
#define __SIMD32_TYPE int32_t
#elif defined ( __CSMC__ )
#define __SIMD32_TYPE int32_t
#elif defined ( __TASKING__ )
#define __SIMD32_TYPE __un(aligned) int32_t
#elif defined(_MSC_VER )
#define __SIMD32_TYPE int32_t
#else
#error Unknown compiler
#endif
#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr))
#define __SIMD32_CONST(addr) ( (__SIMD32_TYPE * ) (addr))
#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE * ) (addr))
#define __SIMD64(addr) (*( int64_t **) & (addr))
/* SIMD replacement */
/**
@brief Read 2 Q15 from Q15 pointer.
@param[in] pQ15 points to input value
@return Q31 value
*/
__STATIC_FORCEINLINE q31_t read_q15x2 (
q15_t const * pQ15)
{
q31_t val;
#ifdef __ARM_FEATURE_UNALIGNED
memcpy (&val, pQ15, 4);
#else
val = (pQ15[1] << 16) | (pQ15[0] & 0x0FFFF) ;
#endif
return (val);
}
/**
@brief Read 2 Q15 from Q15 pointer and increment pointer afterwards.
@param[in] pQ15 points to input value
@return Q31 value
*/
#define read_q15x2_ia(pQ15) read_q15x2((*(pQ15) += 2) - 2)
/**
@brief Read 2 Q15 from Q15 pointer and decrement pointer afterwards.
@param[in] pQ15 points to input value
@return Q31 value
*/
#define read_q15x2_da(pQ15) read_q15x2((*(pQ15) -= 2) + 2)
/**
@brief Write 2 Q15 to Q15 pointer and increment pointer afterwards.
@param[in] pQ15 points to input value
@param[in] value Q31 value
@return none
*/
__STATIC_FORCEINLINE void write_q15x2_ia (
q15_t ** pQ15,
q31_t value)
{
q31_t val = value;
#ifdef __ARM_FEATURE_UNALIGNED
memcpy (*pQ15, &val, 4);
#else
(*pQ15)[0] = (q15_t)(val & 0x0FFFF);
(*pQ15)[1] = (q15_t)((val >> 16) & 0x0FFFF);
#endif
*pQ15 += 2;
}
/**
@brief Write 2 Q15 to Q15 pointer.
@param[in] pQ15 points to input value
@param[in] value Q31 value
@return none
*/
__STATIC_FORCEINLINE void write_q15x2 (
q15_t * pQ15,
q31_t value)
{
q31_t val = value;
#ifdef __ARM_FEATURE_UNALIGNED
memcpy (pQ15, &val, 4);
#else
pQ15[0] = (q15_t)(val & 0x0FFFF);
pQ15[1] = (q15_t)(val >> 16);
#endif
}
/**
@brief Read 4 Q7 from Q7 pointer
@param[in] pQ7 points to input value
@return Q31 value
*/
__STATIC_FORCEINLINE q31_t read_q7x4 (
q7_t const * pQ7)
{
q31_t val;
#ifdef __ARM_FEATURE_UNALIGNED
memcpy (&val, pQ7, 4);
#else
val =((pQ7[3] & 0x0FF) << 24) | ((pQ7[2] & 0x0FF) << 16) | ((pQ7[1] & 0x0FF) << 8) | (pQ7[0] & 0x0FF);
#endif
return (val);
}
/**
@brief Read 4 Q7 from Q7 pointer and increment pointer afterwards.
@param[in] pQ7 points to input value
@return Q31 value
*/
#define read_q7x4_ia(pQ7) read_q7x4((*(pQ7) += 4) - 4)
/**
@brief Read 4 Q7 from Q7 pointer and decrement pointer afterwards.
@param[in] pQ7 points to input value
@return Q31 value
*/
#define read_q7x4_da(pQ7) read_q7x4((*(pQ7) -= 4) + 4)
/**
@brief Write 4 Q7 to Q7 pointer and increment pointer afterwards.
@param[in] pQ7 points to input value
@param[in] value Q31 value
@return none
*/
__STATIC_FORCEINLINE void write_q7x4_ia (
q7_t ** pQ7,
q31_t value)
{
q31_t val = value;
#ifdef __ARM_FEATURE_UNALIGNED
memcpy (*pQ7, &val, 4);
#else
(*pQ7)[0] = (q7_t)(val & 0x0FF);
(*pQ7)[1] = (q7_t)((val >> 8) & 0x0FF);
(*pQ7)[2] = (q7_t)((val >> 16) & 0x0FF);
(*pQ7)[3] = (q7_t)((val >> 24) & 0x0FF);
#endif
*pQ7 += 4;
}
#ifdef __cplusplus
}
#endif
#endif /*ifndef _ARM_MATH_MEMORY_H_ */
@@ -0,0 +1,616 @@
/******************************************************************************
* @file arm_math_types.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2021 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARM_MATH_TYPES_H_
#define _ARM_MATH_TYPES_H_
#ifdef __cplusplus
extern "C"
{
#endif
/* Compiler specific diagnostic adjustment */
#if defined ( __CC_ARM )
#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 )
#elif defined ( __APPLE_CC__ )
#pragma GCC diagnostic ignored "-Wold-style-cast"
#elif defined ( __GNUC__ )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#elif defined ( __ICCARM__ )
#elif defined ( __TI_ARM__ )
#elif defined ( __CSMC__ )
#elif defined ( __TASKING__ )
#elif defined ( _MSC_VER )
#else
#error Unknown compiler
#endif
/* Included for instrinsics definitions */
#if defined (_MSC_VER )
#include <stdint.h>
#define __STATIC_FORCEINLINE static __forceinline
#define __STATIC_INLINE static __inline
#define __ALIGNED(x) __declspec(align(x))
#elif defined ( __APPLE_CC__ )
#include <stdint.h>
#define __ALIGNED(x) __attribute__((aligned(x)))
#define __STATIC_FORCEINLINE static inline __attribute__((always_inline))
#define __STATIC_INLINE static inline
#elif defined (__GNUC_PYTHON__)
#include <stdint.h>
#define __ALIGNED(x) __attribute__((aligned(x)))
#define __STATIC_FORCEINLINE static inline __attribute__((always_inline))
#define __STATIC_INLINE static inline
#else
#include "cmsis_compiler.h"
#endif
#include <string.h>
#include <math.h>
#include <float.h>
#include <limits.h>
/* evaluate ARM DSP feature */
#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1))
#define ARM_MATH_DSP 1
#endif
#if defined(ARM_MATH_NEON)
#if defined(_MSC_VER) && defined(_M_ARM64EC)
#include <arm64_neon.h>
#else
#include <arm_neon.h>
#endif
#if defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
#if !defined(ARM_MATH_NEON_FLOAT16)
#define ARM_MATH_NEON_FLOAT16
#endif
#endif
#endif
#if !defined(ARM_MATH_AUTOVECTORIZE)
#if defined(__ARM_FEATURE_MVE)
#if __ARM_FEATURE_MVE
#if !defined(ARM_MATH_MVEI)
#define ARM_MATH_MVEI
#endif
#endif
#if (__ARM_FEATURE_MVE & 2)
#if !defined(ARM_MATH_MVEF)
#define ARM_MATH_MVEF
#endif
#if !defined(ARM_MATH_MVE_FLOAT16)
#define ARM_MATH_MVE_FLOAT16
#endif
#endif
#endif /*defined(__ARM_FEATURE_MVE)*/
#endif /*!defined(ARM_MATH_AUTOVECTORIZE)*/
#if defined (ARM_MATH_HELIUM)
#if !defined(ARM_MATH_MVEF)
#define ARM_MATH_MVEF
#endif
#if !defined(ARM_MATH_MVEI)
#define ARM_MATH_MVEI
#endif
#if !defined(ARM_MATH_MVE_FLOAT16)
#define ARM_MATH_MVE_FLOAT16
#endif
#endif
#if defined ( __CC_ARM )
/* Enter low optimization region - place directly above function definition */
#if defined( __ARM_ARCH_7EM__ )
#define LOW_OPTIMIZATION_ENTER \
_Pragma ("push") \
_Pragma ("O1")
#else
#define LOW_OPTIMIZATION_ENTER
#endif
/* Exit low optimization region - place directly after end of function definition */
#if defined ( __ARM_ARCH_7EM__ )
#define LOW_OPTIMIZATION_EXIT \
_Pragma ("pop")
#else
#define LOW_OPTIMIZATION_EXIT
#endif
/* Enter low optimization region - place directly above function definition */
#define IAR_ONLY_LOW_OPTIMIZATION_ENTER
/* Exit low optimization region - place directly after end of function definition */
#define IAR_ONLY_LOW_OPTIMIZATION_EXIT
#elif defined (__ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 )
#define LOW_OPTIMIZATION_ENTER
#define LOW_OPTIMIZATION_EXIT
#define IAR_ONLY_LOW_OPTIMIZATION_ENTER
#define IAR_ONLY_LOW_OPTIMIZATION_EXIT
#elif defined ( __APPLE_CC__ )
#define LOW_OPTIMIZATION_ENTER
#define LOW_OPTIMIZATION_EXIT
#define IAR_ONLY_LOW_OPTIMIZATION_ENTER
#define IAR_ONLY_LOW_OPTIMIZATION_EXIT
#elif defined ( __GNUC__ )
#define LOW_OPTIMIZATION_ENTER \
__attribute__(( optimize("-O1") ))
#define LOW_OPTIMIZATION_EXIT
#define IAR_ONLY_LOW_OPTIMIZATION_ENTER
#define IAR_ONLY_LOW_OPTIMIZATION_EXIT
#elif defined ( __ICCARM__ )
/* Enter low optimization region - place directly above function definition */
#if defined ( __ARM_ARCH_7EM__ )
#define LOW_OPTIMIZATION_ENTER \
_Pragma ("optimize=low")
#else
#define LOW_OPTIMIZATION_ENTER
#endif
/* Exit low optimization region - place directly after end of function definition */
#define LOW_OPTIMIZATION_EXIT
/* Enter low optimization region - place directly above function definition */
#if defined ( __ARM_ARCH_7EM__ )
#define IAR_ONLY_LOW_OPTIMIZATION_ENTER \
_Pragma ("optimize=low")
#else
#define IAR_ONLY_LOW_OPTIMIZATION_ENTER
#endif
/* Exit low optimization region - place directly after end of function definition */
#define IAR_ONLY_LOW_OPTIMIZATION_EXIT
#elif defined ( __TI_ARM__ )
#define LOW_OPTIMIZATION_ENTER
#define LOW_OPTIMIZATION_EXIT
#define IAR_ONLY_LOW_OPTIMIZATION_ENTER
#define IAR_ONLY_LOW_OPTIMIZATION_EXIT
#elif defined ( __CSMC__ )
#define LOW_OPTIMIZATION_ENTER
#define LOW_OPTIMIZATION_EXIT
#define IAR_ONLY_LOW_OPTIMIZATION_ENTER
#define IAR_ONLY_LOW_OPTIMIZATION_EXIT
#elif defined ( __TASKING__ )
#define LOW_OPTIMIZATION_ENTER
#define LOW_OPTIMIZATION_EXIT
#define IAR_ONLY_LOW_OPTIMIZATION_ENTER
#define IAR_ONLY_LOW_OPTIMIZATION_EXIT
#elif defined ( _MSC_VER ) || defined(__GNUC_PYTHON__)
#define LOW_OPTIMIZATION_ENTER
#define LOW_OPTIMIZATION_EXIT
#define IAR_ONLY_LOW_OPTIMIZATION_ENTER
#define IAR_ONLY_LOW_OPTIMIZATION_EXIT
#endif
/* Compiler specific diagnostic adjustment */
#if defined ( __CC_ARM )
#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 )
#elif defined ( __APPLE_CC__ )
#elif defined ( __GNUC__ )
#pragma GCC diagnostic pop
#elif defined ( __ICCARM__ )
#elif defined ( __TI_ARM__ )
#elif defined ( __CSMC__ )
#elif defined ( __TASKING__ )
#elif defined ( _MSC_VER )
#else
#error Unknown compiler
#endif
#ifdef __cplusplus
}
#endif
#if defined(__ARM_FEATURE_MVE) && __ARM_FEATURE_MVE
#include <arm_mve.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief 8-bit fractional data type in 1.7 format.
*/
typedef int8_t q7_t;
/**
* @brief 16-bit fractional data type in 1.15 format.
*/
typedef int16_t q15_t;
/**
* @brief 32-bit fractional data type in 1.31 format.
*/
typedef int32_t q31_t;
/**
* @brief 64-bit fractional data type in 1.63 format.
*/
typedef int64_t q63_t;
/**
* @brief 32-bit floating-point type definition.
*/
#if !defined(__ICCARM__) || !(__ARM_FEATURE_MVE & 2)
typedef float float32_t;
#endif
/**
* @brief 64-bit floating-point type definition.
*/
typedef double float64_t;
/**
* @brief vector types
*/
#if defined(ARM_MATH_NEON) || (defined (ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE))
/**
* @brief 64-bit fractional 128-bit vector data type in 1.63 format
*/
typedef int64x2_t q63x2_t;
/**
* @brief 32-bit fractional 128-bit vector data type in 1.31 format.
*/
typedef int32x4_t q31x4_t;
/**
* @brief 16-bit fractional 128-bit vector data type with 16-bit alignment in 1.15 format.
*/
typedef __ALIGNED(2) int16x8_t q15x8_t;
/**
* @brief 8-bit fractional 128-bit vector data type with 8-bit alignment in 1.7 format.
*/
typedef __ALIGNED(1) int8x16_t q7x16_t;
/**
* @brief 32-bit fractional 128-bit vector pair data type in 1.31 format.
*/
typedef int32x4x2_t q31x4x2_t;
/**
* @brief 32-bit fractional 128-bit vector quadruplet data type in 1.31 format.
*/
typedef int32x4x4_t q31x4x4_t;
/**
* @brief 16-bit fractional 128-bit vector pair data type in 1.15 format.
*/
typedef int16x8x2_t q15x8x2_t;
/**
* @brief 16-bit fractional 128-bit vector quadruplet data type in 1.15 format.
*/
typedef int16x8x4_t q15x8x4_t;
/**
* @brief 8-bit fractional 128-bit vector pair data type in 1.7 format.
*/
typedef int8x16x2_t q7x16x2_t;
/**
* @brief 8-bit fractional 128-bit vector quadruplet data type in 1.7 format.
*/
typedef int8x16x4_t q7x16x4_t;
/**
* @brief 32-bit fractional data type in 9.23 format.
*/
typedef int32_t q23_t;
/**
* @brief 32-bit fractional 128-bit vector data type in 9.23 format.
*/
typedef int32x4_t q23x4_t;
/**
* @brief 64-bit status 128-bit vector data type.
*/
typedef int64x2_t status64x2_t;
/**
* @brief 32-bit status 128-bit vector data type.
*/
typedef int32x4_t status32x4_t;
/**
* @brief 16-bit status 128-bit vector data type.
*/
typedef int16x8_t status16x8_t;
/**
* @brief 8-bit status 128-bit vector data type.
*/
typedef int8x16_t status8x16_t;
#endif
#if defined(ARM_MATH_NEON) || (defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)) /* floating point vector*/
/**
* @brief 32-bit floating-point 128-bit vector type
*/
typedef float32x4_t f32x4_t;
/**
* @brief 32-bit floating-point 128-bit vector pair data type
*/
typedef float32x4x2_t f32x4x2_t;
/**
* @brief 32-bit floating-point 128-bit vector quadruplet data type
*/
typedef float32x4x4_t f32x4x4_t;
/**
* @brief 32-bit ubiquitous 128-bit vector data type
*/
typedef union _any32x4_t
{
float32x4_t f;
int32x4_t i;
} any32x4_t;
#endif
#if defined(ARM_MATH_NEON)
/**
* @brief 32-bit fractional 64-bit vector data type in 1.31 format.
*/
typedef int32x2_t q31x2_t;
/**
* @brief 16-bit fractional 64-bit vector data type in 1.15 format.
*/
typedef __ALIGNED(2) int16x4_t q15x4_t;
/**
* @brief 8-bit fractional 64-bit vector data type in 1.7 format.
*/
typedef __ALIGNED(1) int8x8_t q7x8_t;
/**
* @brief 32-bit float 64-bit vector data type.
*/
typedef float32x2_t f32x2_t;
/**
* @brief 32-bit floating-point 128-bit vector triplet data type
*/
typedef float32x4x3_t f32x4x3_t;
/**
* @brief 32-bit fractional 128-bit vector triplet data type in 1.31 format
*/
typedef int32x4x3_t q31x4x3_t;
/**
* @brief 16-bit fractional 128-bit vector triplet data type in 1.15 format
*/
typedef int16x8x3_t q15x8x3_t;
/**
* @brief 8-bit fractional 128-bit vector triplet data type in 1.7 format
*/
typedef int8x16x3_t q7x16x3_t;
/**
* @brief 32-bit floating-point 64-bit vector pair data type
*/
typedef float32x2x2_t f32x2x2_t;
/**
* @brief 32-bit floating-point 64-bit vector triplet data type
*/
typedef float32x2x3_t f32x2x3_t;
/**
* @brief 32-bit floating-point 64-bit vector quadruplet data type
*/
typedef float32x2x4_t f32x2x4_t;
/**
* @brief 32-bit fractional 64-bit vector pair data type in 1.31 format
*/
typedef int32x2x2_t q31x2x2_t;
/**
* @brief 32-bit fractional 64-bit vector triplet data type in 1.31 format
*/
typedef int32x2x3_t q31x2x3_t;
/**
* @brief 32-bit fractional 64-bit vector quadruplet data type in 1.31 format
*/
typedef int32x4x3_t q31x2x4_t;
/**
* @brief 16-bit fractional 64-bit vector pair data type in 1.15 format
*/
typedef int16x4x2_t q15x4x2_t;
/**
* @brief 16-bit fractional 64-bit vector triplet data type in 1.15 format
*/
typedef int16x4x2_t q15x4x3_t;
/**
* @brief 16-bit fractional 64-bit vector quadruplet data type in 1.15 format
*/
typedef int16x4x3_t q15x4x4_t;
/**
* @brief 8-bit fractional 64-bit vector pair data type in 1.7 format
*/
typedef int8x8x2_t q7x8x2_t;
/**
* @brief 8-bit fractional 64-bit vector triplet data type in 1.7 format
*/
typedef int8x8x3_t q7x8x3_t;
/**
* @brief 8-bit fractional 64-bit vector quadruplet data type in 1.7 format
*/
typedef int8x8x4_t q7x8x4_t;
/**
* @brief 32-bit ubiquitous 64-bit vector data type
*/
typedef union _any32x2_t
{
float32x2_t f;
int32x2_t i;
} any32x2_t;
/**
* @brief 32-bit status 64-bit vector data type.
*/
typedef int32x4_t status32x2_t;
/**
* @brief 16-bit status 64-bit vector data type.
*/
typedef int16x8_t status16x4_t;
/**
* @brief 8-bit status 64-bit vector data type.
*/
typedef int8x16_t status8x8_t;
#endif
#define F64_MAX ((float64_t)DBL_MAX)
#define F32_MAX ((float32_t)FLT_MAX)
#define F64_MIN (-DBL_MAX)
#define F32_MIN (-FLT_MAX)
#define F64_ABSMAX ((float64_t)DBL_MAX)
#define F32_ABSMAX ((float32_t)FLT_MAX)
#define F64_ABSMIN ((float64_t)0.0)
#define F32_ABSMIN ((float32_t)0.0)
#define Q31_MAX ((q31_t)(0x7FFFFFFFL))
#define Q15_MAX ((q15_t)(0x7FFF))
#define Q7_MAX ((q7_t)(0x7F))
#define Q31_MIN ((q31_t)(0x80000000L))
#define Q15_MIN ((q15_t)(0x8000))
#define Q7_MIN ((q7_t)(0x80))
#define Q31_ABSMAX ((q31_t)(0x7FFFFFFFL))
#define Q15_ABSMAX ((q15_t)(0x7FFF))
#define Q7_ABSMAX ((q7_t)(0x7F))
#define Q31_ABSMIN ((q31_t)0)
#define Q15_ABSMIN ((q15_t)0)
#define Q7_ABSMIN ((q7_t)0)
/* Dimension C vector space */
#define CMPLX_DIM 2
/**
* @brief Error status returned by some functions in the library.
*/
typedef enum
{
ARM_MATH_SUCCESS = 0, /**< No error */
ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */
ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */
ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation */
ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */
ARM_MATH_SINGULAR = -5, /**< Input matrix is singular and cannot be inverted */
ARM_MATH_TEST_FAILURE = -6, /**< Test Failed */
ARM_MATH_DECOMPOSITION_FAILURE = -7 /**< Decomposition Failed */
} arm_status;
#ifdef __cplusplus
}
#endif
#endif /*ifndef _ARM_MATH_TYPES_H_ */
@@ -0,0 +1,231 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mve_tables.h
* Description: common tables like fft twiddle factors, Bitreverse, reciprocal etc
* used for MVE implementation only
*
* @version V1.10.0
* @date 04 October 2021
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARM_MVE_TABLES_H
#define _ARM_MVE_TABLES_H
#include "arm_math_types.h"
#ifdef __cplusplus
extern "C"
{
#endif
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_16) || defined(ARM_TABLE_TWIDDLECOEF_F32_32)
extern uint32_t rearranged_twiddle_tab_stride1_arr_16_f32[2];
extern uint32_t rearranged_twiddle_tab_stride2_arr_16_f32[2];
extern uint32_t rearranged_twiddle_tab_stride3_arr_16_f32[2];
extern float32_t rearranged_twiddle_stride1_16_f32[8];
extern float32_t rearranged_twiddle_stride2_16_f32[8];
extern float32_t rearranged_twiddle_stride3_16_f32[8];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_64) || defined(ARM_TABLE_TWIDDLECOEF_F32_128)
extern uint32_t rearranged_twiddle_tab_stride1_arr_64_f32[3];
extern uint32_t rearranged_twiddle_tab_stride2_arr_64_f32[3];
extern uint32_t rearranged_twiddle_tab_stride3_arr_64_f32[3];
extern float32_t rearranged_twiddle_stride1_64_f32[40];
extern float32_t rearranged_twiddle_stride2_64_f32[40];
extern float32_t rearranged_twiddle_stride3_64_f32[40];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_256) || defined(ARM_TABLE_TWIDDLECOEF_F32_512)
extern uint32_t rearranged_twiddle_tab_stride1_arr_256_f32[4];
extern uint32_t rearranged_twiddle_tab_stride2_arr_256_f32[4];
extern uint32_t rearranged_twiddle_tab_stride3_arr_256_f32[4];
extern float32_t rearranged_twiddle_stride1_256_f32[168];
extern float32_t rearranged_twiddle_stride2_256_f32[168];
extern float32_t rearranged_twiddle_stride3_256_f32[168];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_1024) || defined(ARM_TABLE_TWIDDLECOEF_F32_2048)
extern uint32_t rearranged_twiddle_tab_stride1_arr_1024_f32[5];
extern uint32_t rearranged_twiddle_tab_stride2_arr_1024_f32[5];
extern uint32_t rearranged_twiddle_tab_stride3_arr_1024_f32[5];
extern float32_t rearranged_twiddle_stride1_1024_f32[680];
extern float32_t rearranged_twiddle_stride2_1024_f32[680];
extern float32_t rearranged_twiddle_stride3_1024_f32[680];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_4096) || defined(ARM_TABLE_TWIDDLECOEF_F32_8192)
extern uint32_t rearranged_twiddle_tab_stride1_arr_4096_f32[6];
extern uint32_t rearranged_twiddle_tab_stride2_arr_4096_f32[6];
extern uint32_t rearranged_twiddle_tab_stride3_arr_4096_f32[6];
extern float32_t rearranged_twiddle_stride1_4096_f32[2728];
extern float32_t rearranged_twiddle_stride2_4096_f32[2728];
extern float32_t rearranged_twiddle_stride3_4096_f32[2728];
#endif
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_16) || defined(ARM_TABLE_TWIDDLECOEF_Q31_32)
extern uint32_t rearranged_twiddle_tab_stride1_arr_16_q31[2];
extern uint32_t rearranged_twiddle_tab_stride2_arr_16_q31[2];
extern uint32_t rearranged_twiddle_tab_stride3_arr_16_q31[2];
extern q31_t rearranged_twiddle_stride1_16_q31[8];
extern q31_t rearranged_twiddle_stride2_16_q31[8];
extern q31_t rearranged_twiddle_stride3_16_q31[8];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_64) || defined(ARM_TABLE_TWIDDLECOEF_Q31_128)
extern uint32_t rearranged_twiddle_tab_stride1_arr_64_q31[3];
extern uint32_t rearranged_twiddle_tab_stride2_arr_64_q31[3];
extern uint32_t rearranged_twiddle_tab_stride3_arr_64_q31[3];
extern q31_t rearranged_twiddle_stride1_64_q31[40];
extern q31_t rearranged_twiddle_stride2_64_q31[40];
extern q31_t rearranged_twiddle_stride3_64_q31[40];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_256) || defined(ARM_TABLE_TWIDDLECOEF_Q31_512)
extern uint32_t rearranged_twiddle_tab_stride1_arr_256_q31[4];
extern uint32_t rearranged_twiddle_tab_stride2_arr_256_q31[4];
extern uint32_t rearranged_twiddle_tab_stride3_arr_256_q31[4];
extern q31_t rearranged_twiddle_stride1_256_q31[168];
extern q31_t rearranged_twiddle_stride2_256_q31[168];
extern q31_t rearranged_twiddle_stride3_256_q31[168];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_1024) || defined(ARM_TABLE_TWIDDLECOEF_Q31_2048)
extern uint32_t rearranged_twiddle_tab_stride1_arr_1024_q31[5];
extern uint32_t rearranged_twiddle_tab_stride2_arr_1024_q31[5];
extern uint32_t rearranged_twiddle_tab_stride3_arr_1024_q31[5];
extern q31_t rearranged_twiddle_stride1_1024_q31[680];
extern q31_t rearranged_twiddle_stride2_1024_q31[680];
extern q31_t rearranged_twiddle_stride3_1024_q31[680];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_4096) || defined(ARM_TABLE_TWIDDLECOEF_Q31_8192)
extern uint32_t rearranged_twiddle_tab_stride1_arr_4096_q31[6];
extern uint32_t rearranged_twiddle_tab_stride2_arr_4096_q31[6];
extern uint32_t rearranged_twiddle_tab_stride3_arr_4096_q31[6];
extern q31_t rearranged_twiddle_stride1_4096_q31[2728];
extern q31_t rearranged_twiddle_stride2_4096_q31[2728];
extern q31_t rearranged_twiddle_stride3_4096_q31[2728];
#endif
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */
#endif /* defined(ARM_MATH_MVEI) */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_16) || defined(ARM_TABLE_TWIDDLECOEF_Q15_32)
extern uint32_t rearranged_twiddle_tab_stride1_arr_16_q15[2];
extern uint32_t rearranged_twiddle_tab_stride2_arr_16_q15[2];
extern uint32_t rearranged_twiddle_tab_stride3_arr_16_q15[2];
extern q15_t rearranged_twiddle_stride1_16_q15[8];
extern q15_t rearranged_twiddle_stride2_16_q15[8];
extern q15_t rearranged_twiddle_stride3_16_q15[8];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_64) || defined(ARM_TABLE_TWIDDLECOEF_Q15_128)
extern uint32_t rearranged_twiddle_tab_stride1_arr_64_q15[3];
extern uint32_t rearranged_twiddle_tab_stride2_arr_64_q15[3];
extern uint32_t rearranged_twiddle_tab_stride3_arr_64_q15[3];
extern q15_t rearranged_twiddle_stride1_64_q15[40];
extern q15_t rearranged_twiddle_stride2_64_q15[40];
extern q15_t rearranged_twiddle_stride3_64_q15[40];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_256) || defined(ARM_TABLE_TWIDDLECOEF_Q15_512)
extern uint32_t rearranged_twiddle_tab_stride1_arr_256_q15[4];
extern uint32_t rearranged_twiddle_tab_stride2_arr_256_q15[4];
extern uint32_t rearranged_twiddle_tab_stride3_arr_256_q15[4];
extern q15_t rearranged_twiddle_stride1_256_q15[168];
extern q15_t rearranged_twiddle_stride2_256_q15[168];
extern q15_t rearranged_twiddle_stride3_256_q15[168];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_1024) || defined(ARM_TABLE_TWIDDLECOEF_Q15_2048)
extern uint32_t rearranged_twiddle_tab_stride1_arr_1024_q15[5];
extern uint32_t rearranged_twiddle_tab_stride2_arr_1024_q15[5];
extern uint32_t rearranged_twiddle_tab_stride3_arr_1024_q15[5];
extern q15_t rearranged_twiddle_stride1_1024_q15[680];
extern q15_t rearranged_twiddle_stride2_1024_q15[680];
extern q15_t rearranged_twiddle_stride3_1024_q15[680];
#endif
#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_4096) || defined(ARM_TABLE_TWIDDLECOEF_Q15_8192)
extern uint32_t rearranged_twiddle_tab_stride1_arr_4096_q15[6];
extern uint32_t rearranged_twiddle_tab_stride2_arr_4096_q15[6];
extern uint32_t rearranged_twiddle_tab_stride3_arr_4096_q15[6];
extern q15_t rearranged_twiddle_stride1_4096_q15[2728];
extern q15_t rearranged_twiddle_stride2_4096_q15[2728];
extern q15_t rearranged_twiddle_stride3_4096_q15[2728];
#endif
#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */
#endif /* defined(ARM_MATH_MVEI) */
#ifdef __cplusplus
}
#endif
#endif /*_ARM_MVE_TABLES_H*/
@@ -0,0 +1,373 @@
/******************************************************************************
* @file arm_vec_math.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2021 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARM_VEC_MATH_H
#define _ARM_VEC_MATH_H
#include "arm_math_types.h"
#include "arm_common_tables.h"
#include "arm_helium_utils.h"
#ifdef __cplusplus
extern "C"
{
#endif
#if (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE)
#define INV_NEWTON_INIT_F32 0x7EF127EA
static const float32_t __logf_rng_f32=0.693147180f;
/* fast inverse approximation (3x newton) */
__STATIC_INLINE f32x4_t vrecip_medprec_f32(
f32x4_t x)
{
q31x4_t m;
f32x4_t b;
any32x4_t xinv;
f32x4_t ax = vabsq(x);
xinv.f = ax;
m = 0x3F800000 - (xinv.i & 0x7F800000);
xinv.i = xinv.i + m;
xinv.f = 1.41176471f - 0.47058824f * xinv.f;
xinv.i = xinv.i + m;
b = 2.0f - xinv.f * ax;
xinv.f = xinv.f * b;
b = 2.0f - xinv.f * ax;
xinv.f = xinv.f * b;
b = 2.0f - xinv.f * ax;
xinv.f = xinv.f * b;
xinv.f = vdupq_m(xinv.f, INFINITY, vcmpeqq(x, 0.0f));
/*
* restore sign
*/
xinv.f = vnegq_m(xinv.f, xinv.f, vcmpltq(x, 0.0f));
return xinv.f;
}
/* fast inverse approximation (4x newton) */
__STATIC_INLINE f32x4_t vrecip_hiprec_f32(
f32x4_t x)
{
q31x4_t m;
f32x4_t b;
any32x4_t xinv;
f32x4_t ax = vabsq(x);
xinv.f = ax;
m = 0x3F800000 - (xinv.i & 0x7F800000);
xinv.i = xinv.i + m;
xinv.f = 1.41176471f - 0.47058824f * xinv.f;
xinv.i = xinv.i + m;
b = 2.0f - xinv.f * ax;
xinv.f = xinv.f * b;
b = 2.0f - xinv.f * ax;
xinv.f = xinv.f * b;
b = 2.0f - xinv.f * ax;
xinv.f = xinv.f * b;
b = 2.0f - xinv.f * ax;
xinv.f = xinv.f * b;
xinv.f = vdupq_m(xinv.f, INFINITY, vcmpeqq(x, 0.0f));
/*
* restore sign
*/
xinv.f = vnegq_m(xinv.f, xinv.f, vcmpltq(x, 0.0f));
return xinv.f;
}
__STATIC_INLINE f32x4_t vdiv_f32(
f32x4_t num, f32x4_t den)
{
return vmulq(num, vrecip_hiprec_f32(den));
}
/**
@brief Single-precision taylor dev.
@param[in] x f32 quad vector input
@param[in] coeffs f32 quad vector coeffs
@return destination f32 quad vector
*/
__STATIC_INLINE f32x4_t vtaylor_polyq_f32(
f32x4_t x,
const float32_t * coeffs)
{
f32x4_t A = vfmasq(vdupq_n_f32(coeffs[4]), x, coeffs[0]);
f32x4_t B = vfmasq(vdupq_n_f32(coeffs[6]), x, coeffs[2]);
f32x4_t C = vfmasq(vdupq_n_f32(coeffs[5]), x, coeffs[1]);
f32x4_t D = vfmasq(vdupq_n_f32(coeffs[7]), x, coeffs[3]);
f32x4_t x2 = vmulq(x, x);
f32x4_t x4 = vmulq(x2, x2);
f32x4_t res = vfmaq(vfmaq_f32(A, B, x2), vfmaq_f32(C, D, x2), x4);
return res;
}
__STATIC_INLINE f32x4_t vmant_exp_f32(
f32x4_t x,
int32x4_t * e)
{
any32x4_t r;
int32x4_t n;
r.f = x;
n = r.i >> 23;
n = n - 127;
r.i = r.i - (n << 23);
*e = n;
return r.f;
}
__STATIC_INLINE f32x4_t vlogq_f32(f32x4_t vecIn)
{
q31x4_t vecExpUnBiased;
f32x4_t vecTmpFlt0, vecTmpFlt1;
f32x4_t vecAcc0, vecAcc1, vecAcc2, vecAcc3;
f32x4_t vecExpUnBiasedFlt;
/*
* extract exponent
*/
vecTmpFlt1 = vmant_exp_f32(vecIn, &vecExpUnBiased);
vecTmpFlt0 = vecTmpFlt1 * vecTmpFlt1;
/*
* a = (__logf_lut_f32[4] * r.f) + (__logf_lut_f32[0]);
*/
vecAcc0 = vdupq_n_f32(__logf_lut_f32[0]);
vecAcc0 = vfmaq(vecAcc0, vecTmpFlt1, __logf_lut_f32[4]);
/*
* b = (__logf_lut_f32[6] * r.f) + (__logf_lut_f32[2]);
*/
vecAcc1 = vdupq_n_f32(__logf_lut_f32[2]);
vecAcc1 = vfmaq(vecAcc1, vecTmpFlt1, __logf_lut_f32[6]);
/*
* c = (__logf_lut_f32[5] * r.f) + (__logf_lut_f32[1]);
*/
vecAcc2 = vdupq_n_f32(__logf_lut_f32[1]);
vecAcc2 = vfmaq(vecAcc2, vecTmpFlt1, __logf_lut_f32[5]);
/*
* d = (__logf_lut_f32[7] * r.f) + (__logf_lut_f32[3]);
*/
vecAcc3 = vdupq_n_f32(__logf_lut_f32[3]);
vecAcc3 = vfmaq(vecAcc3, vecTmpFlt1, __logf_lut_f32[7]);
/*
* a = a + b * xx;
*/
vecAcc0 = vfmaq(vecAcc0, vecAcc1, vecTmpFlt0);
/*
* c = c + d * xx;
*/
vecAcc2 = vfmaq(vecAcc2, vecAcc3, vecTmpFlt0);
/*
* xx = xx * xx;
*/
vecTmpFlt0 = vecTmpFlt0 * vecTmpFlt0;
vecExpUnBiasedFlt = vcvtq_f32_s32(vecExpUnBiased);
/*
* r.f = a + c * xx;
*/
vecAcc0 = vfmaq(vecAcc0, vecAcc2, vecTmpFlt0);
/*
* add exponent
* r.f = r.f + ((float32_t) m) * __logf_rng_f32;
*/
vecAcc0 = vfmaq(vecAcc0, vecExpUnBiasedFlt, __logf_rng_f32);
// set log0 down to -inf
vecAcc0 = vdupq_m(vecAcc0, -INFINITY, vcmpeqq(vecIn, 0.0f));
return vecAcc0;
}
__STATIC_INLINE f32x4_t vexpq_f32(
f32x4_t x)
{
// Perform range reduction [-log(2),log(2)]
int32x4_t m = vcvtq_s32_f32(vmulq_n_f32(x, 1.4426950408f));
f32x4_t val = vfmsq_f32(x, vcvtq_f32_s32(m), vdupq_n_f32(0.6931471805f));
// Polynomial Approximation
f32x4_t poly = vtaylor_polyq_f32(val, exp_tab);
// Reconstruct
poly = (f32x4_t) (vqaddq_s32((q31x4_t) (poly), vqshlq_n_s32(m, 23)));
poly = vdupq_m(poly, 0.0f, vcmpltq_n_s32(m, -126));
return poly;
}
__STATIC_INLINE f32x4_t arm_vec_exponent_f32(f32x4_t x, int32_t nb)
{
f32x4_t r = x;
nb--;
while (nb > 0) {
r = vmulq(r, x);
nb--;
}
return (r);
}
__STATIC_INLINE f32x4_t vrecip_f32(f32x4_t vecIn)
{
f32x4_t vecSx, vecW, vecTmp;
any32x4_t v;
vecSx = vabsq(vecIn);
v.f = vecIn;
v.i = vsubq(vdupq_n_s32(INV_NEWTON_INIT_F32), v.i);
vecW = vmulq(vecSx, v.f);
// v.f = v.f * (8 + w * (-28 + w * (56 + w * (-70 + w *(56 + w * (-28 + w * (8 - w)))))));
vecTmp = vsubq(vdupq_n_f32(8.0f), vecW);
vecTmp = vfmasq(vecW, vecTmp, -28.0f);
vecTmp = vfmasq(vecW, vecTmp, 56.0f);
vecTmp = vfmasq(vecW, vecTmp, -70.0f);
vecTmp = vfmasq(vecW, vecTmp, 56.0f);
vecTmp = vfmasq(vecW, vecTmp, -28.0f);
vecTmp = vfmasq(vecW, vecTmp, 8.0f);
v.f = vmulq(v.f, vecTmp);
v.f = vdupq_m(v.f, INFINITY, vcmpeqq(vecIn, 0.0f));
/*
* restore sign
*/
v.f = vnegq_m(v.f, v.f, vcmpltq(vecIn, 0.0f));
return v.f;
}
__STATIC_INLINE f32x4_t vtanhq_f32(
f32x4_t val)
{
f32x4_t x =
vminnmq_f32(vmaxnmq_f32(val, vdupq_n_f32(-10.f)), vdupq_n_f32(10.0f));
f32x4_t exp2x = vexpq_f32(vmulq_n_f32(x, 2.f));
f32x4_t num = vsubq_n_f32(exp2x, 1.f);
f32x4_t den = vaddq_n_f32(exp2x, 1.f);
f32x4_t tanh = vmulq_f32(num, vrecip_f32(den));
return tanh;
}
__STATIC_INLINE f32x4_t vpowq_f32(
f32x4_t val,
f32x4_t n)
{
return vexpq_f32(vmulq_f32(n, vlogq_f32(val)));
}
#endif /* (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE)*/
#if (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE)
#endif /* (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) */
#if (defined(ARM_MATH_NEON) || defined(ARM_MATH_NEON_EXPERIMENTAL)) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "NEMath.h"
/**
* @brief Vectorized integer exponentiation
* @param[in] x value
* @param[in] nb integer exponent >= 1
* @return x^nb
*
*/
__STATIC_INLINE float32x4_t arm_vec_exponent_f32(float32x4_t x, int32_t nb)
{
float32x4_t r = x;
nb --;
while(nb > 0)
{
r = vmulq_f32(r , x);
nb--;
}
return(r);
}
__STATIC_INLINE float32x4_t __arm_vec_sqrt_f32_neon(float32x4_t x)
{
float32x4_t x1 = vmaxq_f32(x, vdupq_n_f32(FLT_MIN));
float32x4_t e = vrsqrteq_f32(x1);
e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e);
e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e);
return vmulq_f32(x, e);
}
__STATIC_INLINE int16x8_t __arm_vec_sqrt_q15_neon(int16x8_t vec)
{
float32x4_t tempF;
int32x4_t tempHI,tempLO;
tempLO = vmovl_s16(vget_low_s16(vec));
tempF = vcvtq_n_f32_s32(tempLO,15);
tempF = __arm_vec_sqrt_f32_neon(tempF);
tempLO = vcvtq_n_s32_f32(tempF,15);
tempHI = vmovl_s16(vget_high_s16(vec));
tempF = vcvtq_n_f32_s32(tempHI,15);
tempF = __arm_vec_sqrt_f32_neon(tempF);
tempHI = vcvtq_n_s32_f32(tempF,15);
return(vcombine_s16(vqmovn_s32(tempLO),vqmovn_s32(tempHI)));
}
__STATIC_INLINE int32x4_t __arm_vec_sqrt_q31_neon(int32x4_t vec)
{
float32x4_t temp;
temp = vcvtq_n_f32_s32(vec,31);
temp = __arm_vec_sqrt_f32_neon(temp);
return(vcvtq_n_s32_f32(temp,31));
}
#endif /* (defined(ARM_MATH_NEON) || defined(ARM_MATH_NEON_EXPERIMENTAL)) && !defined(ARM_MATH_AUTOVECTORIZE) */
#ifdef __cplusplus
}
#endif
#endif /* _ARM_VEC_MATH_H */
/**
*
* End of file.
*/
@@ -0,0 +1,880 @@
/******************************************************************************
* @file basic_math_functions.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _BASIC_MATH_FUNCTIONS_H_
#define _BASIC_MATH_FUNCTIONS_H_
#include "arm_math_types.h"
#include "arm_math_memory.h"
#include "dsp/none.h"
#include "dsp/utils.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @defgroup groupMath Basic Math Functions
*/
/**
* @brief Q7 vector multiplication.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_mult_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Q15 vector multiplication.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_mult_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Q31 vector multiplication.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_mult_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Floating-point vector multiplication.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_mult_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Floating-point vector multiplication.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_mult_f64(
const float64_t * pSrcA,
const float64_t * pSrcB,
float64_t * pDst,
uint32_t blockSize);
/**
* @brief Floating-point vector addition.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_add_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Floating-point vector addition.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_add_f64(
const float64_t * pSrcA,
const float64_t * pSrcB,
float64_t * pDst,
uint32_t blockSize);
/**
* @brief Q7 vector addition.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_add_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Q15 vector addition.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_add_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Q31 vector addition.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_add_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Floating-point vector subtraction.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_sub_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Floating-point vector subtraction.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_sub_f64(
const float64_t * pSrcA,
const float64_t * pSrcB,
float64_t * pDst,
uint32_t blockSize);
/**
* @brief Q7 vector subtraction.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_sub_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Q15 vector subtraction.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_sub_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Q31 vector subtraction.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in each vector
*/
void arm_sub_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Multiplies a floating-point vector by a scalar.
* @param[in] pSrc points to the input vector
* @param[in] scale scale factor to be applied
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_scale_f32(
const float32_t * pSrc,
float32_t scale,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Multiplies a floating-point vector by a scalar.
* @param[in] pSrc points to the input vector
* @param[in] scale scale factor to be applied
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_scale_f64(
const float64_t * pSrc,
float64_t scale,
float64_t * pDst,
uint32_t blockSize);
/**
* @brief Multiplies a Q7 vector by a scalar.
* @param[in] pSrc points to the input vector
* @param[in] scaleFract fractional portion of the scale value
* @param[in] shift number of bits to shift the result by
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_scale_q7(
const q7_t * pSrc,
q7_t scaleFract,
int8_t shift,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Multiplies a Q15 vector by a scalar.
* @param[in] pSrc points to the input vector
* @param[in] scaleFract fractional portion of the scale value
* @param[in] shift number of bits to shift the result by
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_scale_q15(
const q15_t * pSrc,
q15_t scaleFract,
int8_t shift,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Multiplies a Q31 vector by a scalar.
* @param[in] pSrc points to the input vector
* @param[in] scaleFract fractional portion of the scale value
* @param[in] shift number of bits to shift the result by
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_scale_q31(
const q31_t * pSrc,
q31_t scaleFract,
int8_t shift,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Q7 vector absolute value.
* @param[in] pSrc points to the input buffer
* @param[out] pDst points to the output buffer
* @param[in] blockSize number of samples in each vector
*/
void arm_abs_q7(
const q7_t * pSrc,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Floating-point vector absolute value.
* @param[in] pSrc points to the input buffer
* @param[out] pDst points to the output buffer
* @param[in] blockSize number of samples in each vector
*/
void arm_abs_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Floating-point vector absolute value.
* @param[in] pSrc points to the input buffer
* @param[out] pDst points to the output buffer
* @param[in] blockSize number of samples in each vector
*/
void arm_abs_f64(
const float64_t * pSrc,
float64_t * pDst,
uint32_t blockSize);
/**
* @brief Q15 vector absolute value.
* @param[in] pSrc points to the input buffer
* @param[out] pDst points to the output buffer
* @param[in] blockSize number of samples in each vector
*/
void arm_abs_q15(
const q15_t * pSrc,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Q31 vector absolute value.
* @param[in] pSrc points to the input buffer
* @param[out] pDst points to the output buffer
* @param[in] blockSize number of samples in each vector
*/
void arm_abs_q31(
const q31_t * pSrc,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Dot product of floating-point vectors.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[in] blockSize number of samples in each vector
* @param[out] result output result returned here
*/
void arm_dot_prod_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
uint32_t blockSize,
float32_t * result);
/**
* @brief Dot product of floating-point vectors.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[in] blockSize number of samples in each vector
* @param[out] result output result returned here
*/
void arm_dot_prod_f64(
const float64_t * pSrcA,
const float64_t * pSrcB,
uint32_t blockSize,
float64_t * result);
/**
* @brief Dot product of Q7 vectors.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[in] blockSize number of samples in each vector
* @param[out] result output result returned here
*/
void arm_dot_prod_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
uint32_t blockSize,
q31_t * result);
/**
* @brief Dot product of Q15 vectors.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[in] blockSize number of samples in each vector
* @param[out] result output result returned here
*/
void arm_dot_prod_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
uint32_t blockSize,
q63_t * result);
/**
* @brief Dot product of Q31 vectors.
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[in] blockSize number of samples in each vector
* @param[out] result output result returned here
*/
void arm_dot_prod_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
uint32_t blockSize,
q63_t * result);
/**
* @brief Shifts the elements of a Q7 vector a specified number of bits.
* @param[in] pSrc points to the input vector
* @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_shift_q7(
const q7_t * pSrc,
int8_t shiftBits,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Shifts the elements of a Q15 vector a specified number of bits.
* @param[in] pSrc points to the input vector
* @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_shift_q15(
const q15_t * pSrc,
int8_t shiftBits,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Shifts the elements of a Q31 vector a specified number of bits.
* @param[in] pSrc points to the input vector
* @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_shift_q31(
const q31_t * pSrc,
int8_t shiftBits,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Adds a constant offset to a floating-point vector.
* @param[in] pSrc points to the input vector
* @param[in] offset is the offset to be added
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_offset_f64(
const float64_t * pSrc,
float64_t offset,
float64_t * pDst,
uint32_t blockSize);
/**
* @brief Adds a constant offset to a floating-point vector.
* @param[in] pSrc points to the input vector
* @param[in] offset is the offset to be added
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_offset_f32(
const float32_t * pSrc,
float32_t offset,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Adds a constant offset to a Q7 vector.
* @param[in] pSrc points to the input vector
* @param[in] offset is the offset to be added
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_offset_q7(
const q7_t * pSrc,
q7_t offset,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Adds a constant offset to a Q15 vector.
* @param[in] pSrc points to the input vector
* @param[in] offset is the offset to be added
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_offset_q15(
const q15_t * pSrc,
q15_t offset,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Adds a constant offset to a Q31 vector.
* @param[in] pSrc points to the input vector
* @param[in] offset is the offset to be added
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_offset_q31(
const q31_t * pSrc,
q31_t offset,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Negates the elements of a floating-point vector.
* @param[in] pSrc points to the input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_negate_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Negates the elements of a floating-point vector.
* @param[in] pSrc points to the input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_negate_f64(
const float64_t * pSrc,
float64_t * pDst,
uint32_t blockSize);
/**
* @brief Negates the elements of a Q7 vector.
* @param[in] pSrc points to the input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_negate_q7(
const q7_t * pSrc,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Negates the elements of a Q15 vector.
* @param[in] pSrc points to the input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_negate_q15(
const q15_t * pSrc,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Negates the elements of a Q31 vector.
* @param[in] pSrc points to the input vector
* @param[out] pDst points to the output vector
* @param[in] blockSize number of samples in the vector
*/
void arm_negate_q31(
const q31_t * pSrc,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Compute the logical bitwise AND of two fixed-point vectors.
* @param[in] pSrcA points to input vector A
* @param[in] pSrcB points to input vector B
* @param[out] pDst points to output vector
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_and_u16(
const uint16_t * pSrcA,
const uint16_t * pSrcB,
uint16_t * pDst,
uint32_t blockSize);
/**
* @brief Compute the logical bitwise AND of two fixed-point vectors.
* @param[in] pSrcA points to input vector A
* @param[in] pSrcB points to input vector B
* @param[out] pDst points to output vector
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_and_u32(
const uint32_t * pSrcA,
const uint32_t * pSrcB,
uint32_t * pDst,
uint32_t blockSize);
/**
* @brief Compute the logical bitwise AND of two fixed-point vectors.
* @param[in] pSrcA points to input vector A
* @param[in] pSrcB points to input vector B
* @param[out] pDst points to output vector
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_and_u8(
const uint8_t * pSrcA,
const uint8_t * pSrcB,
uint8_t * pDst,
uint32_t blockSize);
/**
* @brief Compute the logical bitwise OR of two fixed-point vectors.
* @param[in] pSrcA points to input vector A
* @param[in] pSrcB points to input vector B
* @param[out] pDst points to output vector
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_or_u16(
const uint16_t * pSrcA,
const uint16_t * pSrcB,
uint16_t * pDst,
uint32_t blockSize);
/**
* @brief Compute the logical bitwise OR of two fixed-point vectors.
* @param[in] pSrcA points to input vector A
* @param[in] pSrcB points to input vector B
* @param[out] pDst points to output vector
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_or_u32(
const uint32_t * pSrcA,
const uint32_t * pSrcB,
uint32_t * pDst,
uint32_t blockSize);
/**
* @brief Compute the logical bitwise OR of two fixed-point vectors.
* @param[in] pSrcA points to input vector A
* @param[in] pSrcB points to input vector B
* @param[out] pDst points to output vector
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_or_u8(
const uint8_t * pSrcA,
const uint8_t * pSrcB,
uint8_t * pDst,
uint32_t blockSize);
/**
* @brief Compute the logical bitwise NOT of a fixed-point vector.
* @param[in] pSrc points to input vector
* @param[out] pDst points to output vector
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_not_u16(
const uint16_t * pSrc,
uint16_t * pDst,
uint32_t blockSize);
/**
* @brief Compute the logical bitwise NOT of a fixed-point vector.
* @param[in] pSrc points to input vector
* @param[out] pDst points to output vector
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_not_u32(
const uint32_t * pSrc,
uint32_t * pDst,
uint32_t blockSize);
/**
* @brief Compute the logical bitwise NOT of a fixed-point vector.
* @param[in] pSrc points to input vector
* @param[out] pDst points to output vector
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_not_u8(
const uint8_t * pSrc,
uint8_t * pDst,
uint32_t blockSize);
/**
* @brief Compute the logical bitwise XOR of two fixed-point vectors.
* @param[in] pSrcA points to input vector A
* @param[in] pSrcB points to input vector B
* @param[out] pDst points to output vector
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_xor_u16(
const uint16_t * pSrcA,
const uint16_t * pSrcB,
uint16_t * pDst,
uint32_t blockSize);
/**
* @brief Compute the logical bitwise XOR of two fixed-point vectors.
* @param[in] pSrcA points to input vector A
* @param[in] pSrcB points to input vector B
* @param[out] pDst points to output vector
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_xor_u32(
const uint32_t * pSrcA,
const uint32_t * pSrcB,
uint32_t * pDst,
uint32_t blockSize);
/**
* @brief Compute the logical bitwise XOR of two fixed-point vectors.
* @param[in] pSrcA points to input vector A
* @param[in] pSrcB points to input vector B
* @param[out] pDst points to output vector
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_xor_u8(
const uint8_t * pSrcA,
const uint8_t * pSrcB,
uint8_t * pDst,
uint32_t blockSize);
/**
@brief Elementwise floating-point clipping
@param[in] pSrc points to input values
@param[out] pDst points to output clipped values
@param[in] low lower bound
@param[in] high higher bound
@param[in] numSamples number of samples to clip
@return none
*/
void arm_clip_f32(const float32_t * pSrc,
float32_t * pDst,
float32_t low,
float32_t high,
uint32_t numSamples);
/**
@brief Elementwise fixed-point clipping
@param[in] pSrc points to input values
@param[out] pDst points to output clipped values
@param[in] low lower bound
@param[in] high higher bound
@param[in] numSamples number of samples to clip
@return none
*/
void arm_clip_q31(const q31_t * pSrc,
q31_t * pDst,
q31_t low,
q31_t high,
uint32_t numSamples);
/**
@brief Elementwise fixed-point clipping
@param[in] pSrc points to input values
@param[out] pDst points to output clipped values
@param[in] low lower bound
@param[in] high higher bound
@param[in] numSamples number of samples to clip
@return none
*/
void arm_clip_q15(const q15_t * pSrc,
q15_t * pDst,
q15_t low,
q15_t high,
uint32_t numSamples);
/**
@brief Elementwise fixed-point clipping
@param[in] pSrc points to input values
@param[out] pDst points to output clipped values
@param[in] low lower bound
@param[in] high higher bound
@param[in] numSamples number of samples to clip
@return none
*/
void arm_clip_q7(const q7_t * pSrc,
q7_t * pDst,
q7_t low,
q7_t high,
uint32_t numSamples);
#ifdef __cplusplus
}
#endif
#endif /* ifndef _BASIC_MATH_FUNCTIONS_H_ */
@@ -0,0 +1,345 @@
/******************************************************************************
* @file complex_math_functions.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _COMPLEX_MATH_FUNCTIONS_H_
#define _COMPLEX_MATH_FUNCTIONS_H_
#include "arm_math_types.h"
#include "arm_math_memory.h"
#include "dsp/none.h"
#include "dsp/utils.h"
#include "dsp/fast_math_functions.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @defgroup groupCmplxMath Complex Math Functions
* This set of functions operates on complex data vectors.
* The data in the complex arrays is stored in an interleaved fashion
* (real, imag, real, imag, ...).
* In the API functions, the number of samples in a complex array refers
* to the number of complex values; the array contains twice this number of
* real values.
*/
/**
* @brief Floating-point complex conjugate.
* @param[in] pSrc points to the input vector
* @param[out] pDst points to the output vector
* @param[in] numSamples number of complex samples in each vector
*/
void arm_cmplx_conj_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t numSamples);
/**
* @brief Q31 complex conjugate.
* @param[in] pSrc points to the input vector
* @param[out] pDst points to the output vector
* @param[in] numSamples number of complex samples in each vector
*/
void arm_cmplx_conj_q31(
const q31_t * pSrc,
q31_t * pDst,
uint32_t numSamples);
/**
* @brief Q15 complex conjugate.
* @param[in] pSrc points to the input vector
* @param[out] pDst points to the output vector
* @param[in] numSamples number of complex samples in each vector
*/
void arm_cmplx_conj_q15(
const q15_t * pSrc,
q15_t * pDst,
uint32_t numSamples);
/**
* @brief Floating-point complex magnitude squared
* @param[in] pSrc points to the complex input vector
* @param[out] pDst points to the real output vector
* @param[in] numSamples number of complex samples in the input vector
*/
void arm_cmplx_mag_squared_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t numSamples);
/**
* @brief Floating-point complex magnitude squared
* @param[in] pSrc points to the complex input vector
* @param[out] pDst points to the real output vector
* @param[in] numSamples number of complex samples in the input vector
*/
void arm_cmplx_mag_squared_f64(
const float64_t * pSrc,
float64_t * pDst,
uint32_t numSamples);
/**
* @brief Q31 complex magnitude squared
* @param[in] pSrc points to the complex input vector
* @param[out] pDst points to the real output vector
* @param[in] numSamples number of complex samples in the input vector
*/
void arm_cmplx_mag_squared_q31(
const q31_t * pSrc,
q31_t * pDst,
uint32_t numSamples);
/**
* @brief Q15 complex magnitude squared
* @param[in] pSrc points to the complex input vector
* @param[out] pDst points to the real output vector
* @param[in] numSamples number of complex samples in the input vector
*/
void arm_cmplx_mag_squared_q15(
const q15_t * pSrc,
q15_t * pDst,
uint32_t numSamples);
/**
* @brief Floating-point complex magnitude
* @param[in] pSrc points to the complex input vector
* @param[out] pDst points to the real output vector
* @param[in] numSamples number of complex samples in the input vector
*/
void arm_cmplx_mag_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t numSamples);
/**
* @brief Floating-point complex magnitude
* @param[in] pSrc points to the complex input vector
* @param[out] pDst points to the real output vector
* @param[in] numSamples number of complex samples in the input vector
*/
void arm_cmplx_mag_f64(
const float64_t * pSrc,
float64_t * pDst,
uint32_t numSamples);
/**
* @brief Q31 complex magnitude
* @param[in] pSrc points to the complex input vector
* @param[out] pDst points to the real output vector
* @param[in] numSamples number of complex samples in the input vector
*/
void arm_cmplx_mag_q31(
const q31_t * pSrc,
q31_t * pDst,
uint32_t numSamples);
/**
* @brief Q15 complex magnitude
* @param[in] pSrc points to the complex input vector
* @param[out] pDst points to the real output vector
* @param[in] numSamples number of complex samples in the input vector
*/
void arm_cmplx_mag_q15(
const q15_t * pSrc,
q15_t * pDst,
uint32_t numSamples);
/**
* @brief Q15 complex magnitude
* @param[in] pSrc points to the complex input vector
* @param[out] pDst points to the real output vector
* @param[in] numSamples number of complex samples in the input vector
*/
void arm_cmplx_mag_fast_q15(
const q15_t * pSrc,
q15_t * pDst,
uint32_t numSamples);
/**
* @brief Q15 complex dot product
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[in] numSamples number of complex samples in each vector
* @param[out] realResult real part of the result returned here
* @param[out] imagResult imaginary part of the result returned here
*/
void arm_cmplx_dot_prod_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
uint32_t numSamples,
q31_t * realResult,
q31_t * imagResult);
/**
* @brief Q31 complex dot product
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[in] numSamples number of complex samples in each vector
* @param[out] realResult real part of the result returned here
* @param[out] imagResult imaginary part of the result returned here
*/
void arm_cmplx_dot_prod_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
uint32_t numSamples,
q63_t * realResult,
q63_t * imagResult);
/**
* @brief Floating-point complex dot product
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[in] numSamples number of complex samples in each vector
* @param[out] realResult real part of the result returned here
* @param[out] imagResult imaginary part of the result returned here
*/
void arm_cmplx_dot_prod_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
uint32_t numSamples,
float32_t * realResult,
float32_t * imagResult);
/**
* @brief Q15 complex-by-real multiplication
* @param[in] pSrcCmplx points to the complex input vector
* @param[in] pSrcReal points to the real input vector
* @param[out] pCmplxDst points to the complex output vector
* @param[in] numSamples number of samples in each vector
*/
void arm_cmplx_mult_real_q15(
const q15_t * pSrcCmplx,
const q15_t * pSrcReal,
q15_t * pCmplxDst,
uint32_t numSamples);
/**
* @brief Q31 complex-by-real multiplication
* @param[in] pSrcCmplx points to the complex input vector
* @param[in] pSrcReal points to the real input vector
* @param[out] pCmplxDst points to the complex output vector
* @param[in] numSamples number of samples in each vector
*/
void arm_cmplx_mult_real_q31(
const q31_t * pSrcCmplx,
const q31_t * pSrcReal,
q31_t * pCmplxDst,
uint32_t numSamples);
/**
* @brief Floating-point complex-by-real multiplication
* @param[in] pSrcCmplx points to the complex input vector
* @param[in] pSrcReal points to the real input vector
* @param[out] pCmplxDst points to the complex output vector
* @param[in] numSamples number of samples in each vector
*/
void arm_cmplx_mult_real_f32(
const float32_t * pSrcCmplx,
const float32_t * pSrcReal,
float32_t * pCmplxDst,
uint32_t numSamples);
/**
* @brief Q15 complex-by-complex multiplication
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] numSamples number of complex samples in each vector
*/
void arm_cmplx_mult_cmplx_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
q15_t * pDst,
uint32_t numSamples);
/**
* @brief Q31 complex-by-complex multiplication
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] numSamples number of complex samples in each vector
*/
void arm_cmplx_mult_cmplx_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
q31_t * pDst,
uint32_t numSamples);
/**
* @brief Floating-point complex-by-complex multiplication
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] numSamples number of complex samples in each vector
*/
void arm_cmplx_mult_cmplx_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
float32_t * pDst,
uint32_t numSamples);
/**
* @brief Floating-point complex-by-complex multiplication
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[out] pDst points to the output vector
* @param[in] numSamples number of complex samples in each vector
*/
void arm_cmplx_mult_cmplx_f64(
const float64_t * pSrcA,
const float64_t * pSrcB,
float64_t * pDst,
uint32_t numSamples);
#ifdef __cplusplus
}
#endif
#endif /* ifndef _COMPLEX_MATH_FUNCTIONS_H_ */
@@ -0,0 +1,341 @@
/******************************************************************************
* @file distance_functions.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _DISTANCE_FUNCTIONS_H_
#define _DISTANCE_FUNCTIONS_H_
#include "arm_math_types.h"
#include "arm_math_memory.h"
#include "dsp/none.h"
#include "dsp/utils.h"
#include "dsp/statistics_functions.h"
#include "dsp/basic_math_functions.h"
#include "dsp/fast_math_functions.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @defgroup groupDistance Distance functions
*
* Distance functions for use with clustering algorithms.
* There are distance functions for float vectors and boolean vectors.
*
*/
/* 6.14 bug */
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) && (__ARMCC_VERSION < 6150001)
__attribute__((weak)) float __powisf2(float a, int b);
#endif
/**
* @brief Euclidean distance between two vectors
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] blockSize vector length
* @return distance
*
*/
float32_t arm_euclidean_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize);
/**
* @brief Euclidean distance between two vectors
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] blockSize vector length
* @return distance
*
*/
float64_t arm_euclidean_distance_f64(const float64_t *pA,const float64_t *pB, uint32_t blockSize);
/**
* @brief Bray-Curtis distance between two vectors
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] blockSize vector length
* @return distance
*
*/
float32_t arm_braycurtis_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize);
/**
* @brief Canberra distance between two vectors
*
* This function may divide by zero when samples pA[i] and pB[i] are both zero.
* The result of the computation will be correct. So the division per zero may be
* ignored.
*
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] blockSize vector length
* @return distance
*
*/
float32_t arm_canberra_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize);
/**
* @brief Chebyshev distance between two vectors
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] blockSize vector length
* @return distance
*
*/
float32_t arm_chebyshev_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize);
/**
* @brief Chebyshev distance between two vectors
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] blockSize vector length
* @return distance
*
*/
float64_t arm_chebyshev_distance_f64(const float64_t *pA,const float64_t *pB, uint32_t blockSize);
/**
* @brief Cityblock (Manhattan) distance between two vectors
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] blockSize vector length
* @return distance
*
*/
float32_t arm_cityblock_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize);
/**
* @brief Cityblock (Manhattan) distance between two vectors
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] blockSize vector length
* @return distance
*
*/
float64_t arm_cityblock_distance_f64(const float64_t *pA,const float64_t *pB, uint32_t blockSize);
/**
* @brief Correlation distance between two vectors
*
* The input vectors are modified in place !
*
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] blockSize vector length
* @return distance
*
*/
float32_t arm_correlation_distance_f32(float32_t *pA,float32_t *pB, uint32_t blockSize);
/**
* @brief Cosine distance between two vectors
*
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] blockSize vector length
* @return distance
*
*/
float32_t arm_cosine_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize);
/**
* @brief Cosine distance between two vectors
*
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] blockSize vector length
* @return distance
*
*/
float64_t arm_cosine_distance_f64(const float64_t *pA,const float64_t *pB, uint32_t blockSize);
/**
* @brief Jensen-Shannon distance between two vectors
*
* This function is assuming that elements of second vector are > 0
* and 0 only when the corresponding element of first vector is 0.
* Otherwise the result of the computation does not make sense
* and for speed reasons, the cases returning NaN or Infinity are not
* managed.
*
* When the function is computing x log (x / y) with x 0 and y 0,
* it will compute the right value (0) but a division per zero will occur
* and shoudl be ignored in client code.
*
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] blockSize vector length
* @return distance
*
*/
float32_t arm_jensenshannon_distance_f32(const float32_t *pA,const float32_t *pB,uint32_t blockSize);
/**
* @brief Minkowski distance between two vectors
*
* @param[in] pA First vector
* @param[in] pB Second vector
* @param[in] n Norm order (>= 2)
* @param[in] blockSize vector length
* @return distance
*
*/
float32_t arm_minkowski_distance_f32(const float32_t *pA,const float32_t *pB, int32_t order, uint32_t blockSize);
/**
* @brief Dice distance between two vectors
*
* @param[in] pA First vector of packed booleans
* @param[in] pB Second vector of packed booleans
* @param[in] order Distance order
* @param[in] blockSize Number of samples
* @return distance
*
*/
float32_t arm_dice_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
/**
* @brief Hamming distance between two vectors
*
* @param[in] pA First vector of packed booleans
* @param[in] pB Second vector of packed booleans
* @param[in] numberOfBools Number of booleans
* @return distance
*
*/
float32_t arm_hamming_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
/**
* @brief Jaccard distance between two vectors
*
* @param[in] pA First vector of packed booleans
* @param[in] pB Second vector of packed booleans
* @param[in] numberOfBools Number of booleans
* @return distance
*
*/
float32_t arm_jaccard_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
/**
* @brief Kulsinski distance between two vectors
*
* @param[in] pA First vector of packed booleans
* @param[in] pB Second vector of packed booleans
* @param[in] numberOfBools Number of booleans
* @return distance
*
*/
float32_t arm_kulsinski_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
/**
* @brief Roger Stanimoto distance between two vectors
*
* @param[in] pA First vector of packed booleans
* @param[in] pB Second vector of packed booleans
* @param[in] numberOfBools Number of booleans
* @return distance
*
*/
float32_t arm_rogerstanimoto_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
/**
* @brief Russell-Rao distance between two vectors
*
* @param[in] pA First vector of packed booleans
* @param[in] pB Second vector of packed booleans
* @param[in] numberOfBools Number of booleans
* @return distance
*
*/
float32_t arm_russellrao_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
/**
* @brief Sokal-Michener distance between two vectors
*
* @param[in] pA First vector of packed booleans
* @param[in] pB Second vector of packed booleans
* @param[in] numberOfBools Number of booleans
* @return distance
*
*/
float32_t arm_sokalmichener_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
/**
* @brief Sokal-Sneath distance between two vectors
*
* @param[in] pA First vector of packed booleans
* @param[in] pB Second vector of packed booleans
* @param[in] numberOfBools Number of booleans
* @return distance
*
*/
float32_t arm_sokalsneath_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
/**
* @brief Yule distance between two vectors
*
* @param[in] pA First vector of packed booleans
* @param[in] pB Second vector of packed booleans
* @param[in] numberOfBools Number of booleans
* @return distance
*
*/
float32_t arm_yule_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
#ifdef __cplusplus
}
#endif
#endif /* ifndef _DISTANCE_FUNCTIONS_H_ */
@@ -0,0 +1,389 @@
/******************************************************************************
* @file fast_math_functions.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _FAST_MATH_FUNCTIONS_H_
#define _FAST_MATH_FUNCTIONS_H_
#include "arm_math_types.h"
#include "arm_math_memory.h"
#include "dsp/none.h"
#include "dsp/utils.h"
#include "dsp/basic_math_functions.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Macros required for SINE and COSINE Fast math approximations
*/
#define FAST_MATH_TABLE_SIZE 512
#define FAST_MATH_Q31_SHIFT (32 - 10)
#define FAST_MATH_Q15_SHIFT (16 - 10)
#ifndef PI
#define PI 3.14159265358979f
#endif
/**
* @defgroup groupFastMath Fast Math Functions
* This set of functions provides a fast approximation to sine, cosine, and square root.
* As compared to most of the other functions in the CMSIS math library, the fast math functions
* operate on individual values and not arrays.
* There are separate functions for Q15, Q31, and floating-point data.
*
*/
/**
* @ingroup groupFastMath
*/
/**
@addtogroup sin
@{
*/
/**
* @brief Fast approximation to the trigonometric sine function for floating-point data.
* @param[in] x input value in radians.
* @return sin(x).
*/
float32_t arm_sin_f32(
float32_t x);
/**
* @brief Fast approximation to the trigonometric sine function for Q31 data.
* @param[in] x Scaled input value in radians.
* @return sin(x).
*/
q31_t arm_sin_q31(
q31_t x);
/**
* @brief Fast approximation to the trigonometric sine function for Q15 data.
* @param[in] x Scaled input value in radians.
* @return sin(x).
*/
q15_t arm_sin_q15(
q15_t x);
/**
@} end of sin group
*/
/**
@addtogroup cos
@{
*/
/**
* @brief Fast approximation to the trigonometric cosine function for floating-point data.
* @param[in] x input value in radians.
* @return cos(x).
*/
float32_t arm_cos_f32(
float32_t x);
/**
* @brief Fast approximation to the trigonometric cosine function for Q31 data.
* @param[in] x Scaled input value in radians.
* @return cos(x).
*/
q31_t arm_cos_q31(
q31_t x);
/**
* @brief Fast approximation to the trigonometric cosine function for Q15 data.
* @param[in] x Scaled input value in radians.
* @return cos(x).
*/
q15_t arm_cos_q15(
q15_t x);
/**
@} end of cos group
*/
/**
@brief Floating-point vector of log values.
@param[in] pSrc points to the input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_vlog_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
@brief Floating-point vector of log values.
@param[in] pSrc points to the input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_vlog_f64(
const float64_t * pSrc,
float64_t * pDst,
uint32_t blockSize);
/**
* @brief q31 vector of log values.
* @param[in] pSrc points to the input vector in q31
* @param[out] pDst points to the output vector in q5.26
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_vlog_q31(const q31_t * pSrc,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief q15 vector of log values.
* @param[in] pSrc points to the input vector in q15
* @param[out] pDst points to the output vector in q4.11
* @param[in] blockSize number of samples in each vector
* @return none
*/
void arm_vlog_q15(const q15_t * pSrc,
q15_t * pDst,
uint32_t blockSize);
/**
@brief Floating-point vector of exp values.
@param[in] pSrc points to the input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_vexp_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
@brief Floating-point vector of exp values.
@param[in] pSrc points to the input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_vexp_f64(
const float64_t * pSrc,
float64_t * pDst,
uint32_t blockSize);
/**
* @defgroup SQRT Square Root
*
* Computes the square root of a number.
* There are separate functions for Q15, Q31, and floating-point data types.
* The square root function is computed using the Newton-Raphson algorithm.
* This is an iterative algorithm of the form:
* <pre>
* x1 = x0 - f(x0)/f'(x0)
* </pre>
* where <code>x1</code> is the current estimate,
* <code>x0</code> is the previous estimate, and
* <code>f'(x0)</code> is the derivative of <code>f()</code> evaluated at <code>x0</code>.
* For the square root function, the algorithm reduces to:
* <pre>
* x0 = in/2 [initial guess]
* x1 = 1/2 * ( x0 + in / x0) [each iteration]
* </pre>
*/
/**
* @addtogroup SQRT
* @{
*/
/**
@brief Floating-point square root function.
@param[in] in input value
@param[out] pOut square root of input value
@return execution status
- \ref ARM_MATH_SUCCESS : input value is positive
- \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0
*/
__STATIC_FORCEINLINE arm_status arm_sqrt_f32(
const float32_t in,
float32_t * pOut)
{
if (in >= 0.0f)
{
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
*pOut = __sqrtf(in);
#else
*pOut = sqrtf(in);
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
__ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in));
#else
*pOut = sqrtf(in);
#endif
#else
*pOut = sqrtf(in);
#endif
return (ARM_MATH_SUCCESS);
}
else
{
*pOut = 0.0f;
return (ARM_MATH_ARGUMENT_ERROR);
}
}
/**
@brief Q31 square root function.
@param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF
@param[out] pOut points to square root of input value
@return execution status
- \ref ARM_MATH_SUCCESS : input value is positive
- \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0
*/
arm_status arm_sqrt_q31(
q31_t in,
q31_t * pOut);
/**
@brief Q15 square root function.
@param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF
@param[out] pOut points to square root of input value
@return execution status
- \ref ARM_MATH_SUCCESS : input value is positive
- \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0
*/
arm_status arm_sqrt_q15(
q15_t in,
q15_t * pOut);
/**
* @} end of SQRT group
*/
/**
@brief Fixed point division
@param[in] numerator Numerator
@param[in] denominator Denominator
@param[out] quotient Quotient value normalized between -1.0 and 1.0
@param[out] shift Shift left value to get the unnormalized quotient
@return error status
When dividing by 0, an error ARM_MATH_NANINF is returned. And the quotient is forced
to the saturated negative or positive value.
*/
arm_status arm_divide_q15(q15_t numerator,
q15_t denominator,
q15_t *quotient,
int16_t *shift);
/**
@brief Fixed point division
@param[in] numerator Numerator
@param[in] denominator Denominator
@param[out] quotient Quotient value normalized between -1.0 and 1.0
@param[out] shift Shift left value to get the unnormalized quotient
@return error status
When dividing by 0, an error ARM_MATH_NANINF is returned. And the quotient is forced
to the saturated negative or positive value.
*/
arm_status arm_divide_q31(q31_t numerator,
q31_t denominator,
q31_t *quotient,
int16_t *shift);
/**
@brief Arc tangent in radian of y/x using sign of x and y to determine right quadrant.
@param[in] y y coordinate
@param[in] x x coordinate
@param[out] result Result
@return error status.
*/
arm_status arm_atan2_f32(float32_t y,float32_t x,float32_t *result);
/**
@brief Arc tangent in radian of y/x using sign of x and y to determine right quadrant.
@param[in] y y coordinate
@param[in] x x coordinate
@param[out] result Result in Q2.29
@return error status.
*/
arm_status arm_atan2_q31(q31_t y,q31_t x,q31_t *result);
/**
@brief Arc tangent in radian of y/x using sign of x and y to determine right quadrant.
@param[in] y y coordinate
@param[in] x x coordinate
@param[out] result Result in Q2.13
@return error status.
*/
arm_status arm_atan2_q15(q15_t y,q15_t x,q15_t *result);
#ifdef __cplusplus
}
#endif
#endif /* ifndef _FAST_MATH_FUNCTIONS_H_ */
@@ -0,0 +1,319 @@
/******************************************************************************
* @file interpolation_functions.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _INTERPOLATION_FUNCTIONS_H_
#define _INTERPOLATION_FUNCTIONS_H_
#include "arm_math_types.h"
#include "arm_math_memory.h"
#include "dsp/none.h"
#include "dsp/utils.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @defgroup groupInterpolation Interpolation Functions
* These functions perform 1- and 2-dimensional interpolation of data.
* Linear interpolation is used for 1-dimensional data and
* bilinear interpolation is used for 2-dimensional data.
*/
/**
* @brief Instance structure for the floating-point Linear Interpolate function.
*/
typedef struct
{
uint32_t nValues; /**< nValues */
float32_t x1; /**< x1 */
float32_t xSpacing; /**< xSpacing */
float32_t *pYData; /**< pointer to the table of Y values */
} arm_linear_interp_instance_f32;
/**
* @brief Instance structure for the floating-point bilinear interpolation function.
*/
typedef struct
{
uint16_t numRows; /**< number of rows in the data table. */
uint16_t numCols; /**< number of columns in the data table. */
float32_t *pData; /**< points to the data table. */
} arm_bilinear_interp_instance_f32;
/**
* @brief Instance structure for the Q31 bilinear interpolation function.
*/
typedef struct
{
uint16_t numRows; /**< number of rows in the data table. */
uint16_t numCols; /**< number of columns in the data table. */
q31_t *pData; /**< points to the data table. */
} arm_bilinear_interp_instance_q31;
/**
* @brief Instance structure for the Q15 bilinear interpolation function.
*/
typedef struct
{
uint16_t numRows; /**< number of rows in the data table. */
uint16_t numCols; /**< number of columns in the data table. */
q15_t *pData; /**< points to the data table. */
} arm_bilinear_interp_instance_q15;
/**
* @brief Instance structure for the Q15 bilinear interpolation function.
*/
typedef struct
{
uint16_t numRows; /**< number of rows in the data table. */
uint16_t numCols; /**< number of columns in the data table. */
q7_t *pData; /**< points to the data table. */
} arm_bilinear_interp_instance_q7;
/**
* @brief Struct for specifying cubic spline type
*/
typedef enum
{
ARM_SPLINE_NATURAL = 0, /**< Natural spline */
ARM_SPLINE_PARABOLIC_RUNOUT = 1 /**< Parabolic runout spline */
} arm_spline_type;
/**
* @brief Instance structure for the floating-point cubic spline interpolation.
*/
typedef struct
{
arm_spline_type type; /**< Type (boundary conditions) */
const float32_t * x; /**< x values */
const float32_t * y; /**< y values */
uint32_t n_x; /**< Number of known data points */
float32_t * coeffs; /**< Coefficients buffer (b,c, and d) */
} arm_spline_instance_f32;
/**
* @ingroup groupInterpolation
*/
/**
* @addtogroup SplineInterpolate
* @{
*/
/**
* @brief Processing function for the floating-point cubic spline interpolation.
* @param[in] S points to an instance of the floating-point spline structure.
* @param[in] xq points to the x values ot the interpolated data points.
* @param[out] pDst points to the block of output data.
* @param[in] blockSize number of samples of output data.
*/
void arm_spline_f32(
arm_spline_instance_f32 * S,
const float32_t * xq,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Initialization function for the floating-point cubic spline interpolation.
* @param[in,out] S points to an instance of the floating-point spline structure.
* @param[in] type type of cubic spline interpolation (boundary conditions)
* @param[in] x points to the x values of the known data points.
* @param[in] y points to the y values of the known data points.
* @param[in] n number of known data points.
* @param[in] coeffs coefficients array for b, c, and d
* @param[in] tempBuffer buffer array for internal computations
*/
void arm_spline_init_f32(
arm_spline_instance_f32 * S,
arm_spline_type type,
const float32_t * x,
const float32_t * y,
uint32_t n,
float32_t * coeffs,
float32_t * tempBuffer);
/**
* @} end of SplineInterpolate group
*/
/**
* @addtogroup LinearInterpolate
* @{
*/
/**
* @brief Process function for the floating-point Linear Interpolation Function.
* @param[in,out] S is an instance of the floating-point Linear Interpolation structure
* @param[in] x input sample to process
* @return y processed output sample.
*
*/
float32_t arm_linear_interp_f32(
arm_linear_interp_instance_f32 * S,
float32_t x);
/**
*
* @brief Process function for the Q31 Linear Interpolation Function.
* @param[in] pYData pointer to Q31 Linear Interpolation table
* @param[in] x input sample to process
* @param[in] nValues number of table values
* @return y processed output sample.
*
* \par
* Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
* This function can support maximum of table size 2^12.
*
*/
q31_t arm_linear_interp_q31(
const q31_t * pYData,
q31_t x,
uint32_t nValues);
/**
*
* @brief Process function for the Q15 Linear Interpolation Function.
* @param[in] pYData pointer to Q15 Linear Interpolation table
* @param[in] x input sample to process
* @param[in] nValues number of table values
* @return y processed output sample.
*
* \par
* Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
* This function can support maximum of table size 2^12.
*
*/
q15_t arm_linear_interp_q15(
const q15_t * pYData,
q31_t x,
uint32_t nValues);
/**
*
* @brief Process function for the Q7 Linear Interpolation Function.
* @param[in] pYData pointer to Q7 Linear Interpolation table
* @param[in] x input sample to process
* @param[in] nValues number of table values
* @return y processed output sample.
*
* \par
* Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
* This function can support maximum of table size 2^12.
*/
q7_t arm_linear_interp_q7(
const q7_t * pYData,
q31_t x,
uint32_t nValues);
/**
* @} end of LinearInterpolate group
*/
/**
* @ingroup groupInterpolation
*/
/**
* @addtogroup BilinearInterpolate
* @{
*/
/**
* @brief Floating-point bilinear interpolation.
* @param[in,out] S points to an instance of the interpolation structure.
* @param[in] X interpolation coordinate.
* @param[in] Y interpolation coordinate.
* @return out interpolated value.
*/
float32_t arm_bilinear_interp_f32(
const arm_bilinear_interp_instance_f32 * S,
float32_t X,
float32_t Y);
/**
* @brief Q31 bilinear interpolation.
* @param[in,out] S points to an instance of the interpolation structure.
* @param[in] X interpolation coordinate in 12.20 format.
* @param[in] Y interpolation coordinate in 12.20 format.
* @return out interpolated value.
*/
q31_t arm_bilinear_interp_q31(
arm_bilinear_interp_instance_q31 * S,
q31_t X,
q31_t Y);
/**
* @brief Q15 bilinear interpolation.
* @param[in,out] S points to an instance of the interpolation structure.
* @param[in] X interpolation coordinate in 12.20 format.
* @param[in] Y interpolation coordinate in 12.20 format.
* @return out interpolated value.
*/
q15_t arm_bilinear_interp_q15(
arm_bilinear_interp_instance_q15 * S,
q31_t X,
q31_t Y);
/**
* @brief Q7 bilinear interpolation.
* @param[in,out] S points to an instance of the interpolation structure.
* @param[in] X interpolation coordinate in 12.20 format.
* @param[in] Y interpolation coordinate in 12.20 format.
* @return out interpolated value.
*/
q7_t arm_bilinear_interp_q7(
arm_bilinear_interp_instance_q7 * S,
q31_t X,
q31_t Y);
/**
* @} end of BilinearInterpolate group
*/
#ifdef __cplusplus
}
#endif
#endif /* ifndef _INTERPOLATION_FUNCTIONS_H_ */
@@ -0,0 +1,774 @@
/******************************************************************************
* @file matrix_functions.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _MATRIX_FUNCTIONS_H_
#define _MATRIX_FUNCTIONS_H_
#include "arm_math_types.h"
#include "arm_math_memory.h"
#include "dsp/none.h"
#include "dsp/utils.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @defgroup groupMatrix Matrix Functions
*
* This set of functions provides basic matrix math operations.
* The functions operate on matrix data structures. For example,
* the type
* definition for the floating-point matrix structure is shown
* below:
* <pre>
* typedef struct
* {
* uint16_t numRows; // number of rows of the matrix.
* uint16_t numCols; // number of columns of the matrix.
* float32_t *pData; // points to the data of the matrix.
* } arm_matrix_instance_f32;
* </pre>
* There are similar definitions for Q15 and Q31 data types.
*
* The structure specifies the size of the matrix and then points to
* an array of data. The array is of size <code>numRows X numCols</code>
* and the values are arranged in row order. That is, the
* matrix element (i, j) is stored at:
* <pre>
* pData[i*numCols + j]
* </pre>
*
* \par Init Functions
* There is an associated initialization function for each type of matrix
* data structure.
* The initialization function sets the values of the internal structure fields.
* Refer to \ref arm_mat_init_f32(), \ref arm_mat_init_q31() and \ref arm_mat_init_q15()
* for floating-point, Q31 and Q15 types, respectively.
*
* \par
* Use of the initialization function is optional. However, if initialization function is used
* then the instance structure cannot be placed into a const data section.
* To place the instance structure in a const data
* section, manually initialize the data structure. For example:
* <pre>
* <code>arm_matrix_instance_f32 S = {nRows, nColumns, pData};</code>
* <code>arm_matrix_instance_q31 S = {nRows, nColumns, pData};</code>
* <code>arm_matrix_instance_q15 S = {nRows, nColumns, pData};</code>
* </pre>
* where <code>nRows</code> specifies the number of rows, <code>nColumns</code>
* specifies the number of columns, and <code>pData</code> points to the
* data array.
*
* \par Size Checking
* By default all of the matrix functions perform size checking on the input and
* output matrices. For example, the matrix addition function verifies that the
* two input matrices and the output matrix all have the same number of rows and
* columns. If the size check fails the functions return:
* <pre>
* ARM_MATH_SIZE_MISMATCH
* </pre>
* Otherwise the functions return
* <pre>
* ARM_MATH_SUCCESS
* </pre>
* There is some overhead associated with this matrix size checking.
* The matrix size checking is enabled via the \#define
* <pre>
* ARM_MATH_MATRIX_CHECK
* </pre>
* within the library project settings. By default this macro is defined
* and size checking is enabled. By changing the project settings and
* undefining this macro size checking is eliminated and the functions
* run a bit faster. With size checking disabled the functions always
* return <code>ARM_MATH_SUCCESS</code>.
*/
/**
* @brief Instance structure for the floating-point matrix structure.
*/
typedef struct
{
uint16_t numRows; /**< number of rows of the matrix. */
uint16_t numCols; /**< number of columns of the matrix. */
float32_t *pData; /**< points to the data of the matrix. */
} arm_matrix_instance_f32;
/**
* @brief Instance structure for the floating-point matrix structure.
*/
typedef struct
{
uint16_t numRows; /**< number of rows of the matrix. */
uint16_t numCols; /**< number of columns of the matrix. */
float64_t *pData; /**< points to the data of the matrix. */
} arm_matrix_instance_f64;
/**
* @brief Instance structure for the Q7 matrix structure.
*/
typedef struct
{
uint16_t numRows; /**< number of rows of the matrix. */
uint16_t numCols; /**< number of columns of the matrix. */
q7_t *pData; /**< points to the data of the matrix. */
} arm_matrix_instance_q7;
/**
* @brief Instance structure for the Q15 matrix structure.
*/
typedef struct
{
uint16_t numRows; /**< number of rows of the matrix. */
uint16_t numCols; /**< number of columns of the matrix. */
q15_t *pData; /**< points to the data of the matrix. */
} arm_matrix_instance_q15;
/**
* @brief Instance structure for the Q31 matrix structure.
*/
typedef struct
{
uint16_t numRows; /**< number of rows of the matrix. */
uint16_t numCols; /**< number of columns of the matrix. */
q31_t *pData; /**< points to the data of the matrix. */
} arm_matrix_instance_q31;
/**
* @brief Floating-point matrix addition.
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_add_f32(
const arm_matrix_instance_f32 * pSrcA,
const arm_matrix_instance_f32 * pSrcB,
arm_matrix_instance_f32 * pDst);
/**
* @brief Q15 matrix addition.
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_add_q15(
const arm_matrix_instance_q15 * pSrcA,
const arm_matrix_instance_q15 * pSrcB,
arm_matrix_instance_q15 * pDst);
/**
* @brief Q31 matrix addition.
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_add_q31(
const arm_matrix_instance_q31 * pSrcA,
const arm_matrix_instance_q31 * pSrcB,
arm_matrix_instance_q31 * pDst);
/**
* @brief Floating-point, complex, matrix multiplication.
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_cmplx_mult_f32(
const arm_matrix_instance_f32 * pSrcA,
const arm_matrix_instance_f32 * pSrcB,
arm_matrix_instance_f32 * pDst);
arm_status arm_mat_cmplx_inv_f32_4x4(
const arm_matrix_instance_f32 * pSrc,
arm_matrix_instance_f32 * pDst,
arm_matrix_instance_f32 * pReshapeMat,
float32_t * pInv);
/**
* @brief Q15, complex, matrix multiplication.
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_cmplx_mult_q15(
const arm_matrix_instance_q15 * pSrcA,
const arm_matrix_instance_q15 * pSrcB,
arm_matrix_instance_q15 * pDst,
q15_t * pScratch);
/**
* @brief Q31, complex, matrix multiplication.
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_cmplx_mult_q31(
const arm_matrix_instance_q31 * pSrcA,
const arm_matrix_instance_q31 * pSrcB,
arm_matrix_instance_q31 * pDst);
/**
* @brief Floating-point matrix transpose.
* @param[in] pSrc points to the input matrix
* @param[out] pDst points to the output matrix
* @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
* or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_trans_f32(
const arm_matrix_instance_f32 * pSrc,
arm_matrix_instance_f32 * pDst);
/**
* @brief Floating-point matrix transpose.
* @param[in] pSrc points to the input matrix
* @param[out] pDst points to the output matrix
* @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
* or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_trans_f64(
const arm_matrix_instance_f64 * pSrc,
arm_matrix_instance_f64 * pDst);
/**
* @brief Floating-point complex matrix transpose.
* @param[in] pSrc points to the input matrix
* @param[out] pDst points to the output matrix
* @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
* or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_cmplx_trans_f32(
const arm_matrix_instance_f32 * pSrc,
arm_matrix_instance_f32 * pDst);
/**
* @brief Q15 matrix transpose.
* @param[in] pSrc points to the input matrix
* @param[out] pDst points to the output matrix
* @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
* or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_trans_q15(
const arm_matrix_instance_q15 * pSrc,
arm_matrix_instance_q15 * pDst);
/**
* @brief Q15 complex matrix transpose.
* @param[in] pSrc points to the input matrix
* @param[out] pDst points to the output matrix
* @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
* or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_cmplx_trans_q15(
const arm_matrix_instance_q15 * pSrc,
arm_matrix_instance_q15 * pDst);
/**
* @brief Q7 matrix transpose.
* @param[in] pSrc points to the input matrix
* @param[out] pDst points to the output matrix
* @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
* or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_trans_q7(
const arm_matrix_instance_q7 * pSrc,
arm_matrix_instance_q7 * pDst);
/**
* @brief Q31 matrix transpose.
* @param[in] pSrc points to the input matrix
* @param[out] pDst points to the output matrix
* @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
* or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_trans_q31(
const arm_matrix_instance_q31 * pSrc,
arm_matrix_instance_q31 * pDst);
/**
* @brief Q31 complex matrix transpose.
* @param[in] pSrc points to the input matrix
* @param[out] pDst points to the output matrix
* @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
* or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_cmplx_trans_q31(
const arm_matrix_instance_q31 * pSrc,
arm_matrix_instance_q31 * pDst);
/**
* @brief Floating-point matrix multiplication
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_mult_f32(
const arm_matrix_instance_f32 * pSrcA,
const arm_matrix_instance_f32 * pSrcB,
arm_matrix_instance_f32 * pDst);
/**
* @brief Floating-point matrix multiplication
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_mult_f64(
const arm_matrix_instance_f64 * pSrcA,
const arm_matrix_instance_f64 * pSrcB,
arm_matrix_instance_f64 * pDst);
/**
* @brief Floating-point matrix and vector multiplication
* @param[in] pSrcMat points to the input matrix structure
* @param[in] pVec points to vector
* @param[out] pDst points to output vector
*/
void arm_mat_vec_mult_f32(
const arm_matrix_instance_f32 *pSrcMat,
const float32_t *pVec,
float32_t *pDst);
/**
* @brief Q7 matrix multiplication
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @param[in] pState points to the array for storing intermediate results
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_mult_q7(
const arm_matrix_instance_q7 * pSrcA,
const arm_matrix_instance_q7 * pSrcB,
arm_matrix_instance_q7 * pDst,
q7_t * pState);
/**
* @brief Q7 matrix and vector multiplication
* @param[in] pSrcMat points to the input matrix structure
* @param[in] pVec points to vector
* @param[out] pDst points to output vector
*/
void arm_mat_vec_mult_q7(
const arm_matrix_instance_q7 *pSrcMat,
const q7_t *pVec,
q7_t *pDst);
/**
* @brief Q15 matrix multiplication
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @param[in] pState points to the array for storing intermediate results
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_mult_q15(
const arm_matrix_instance_q15 * pSrcA,
const arm_matrix_instance_q15 * pSrcB,
arm_matrix_instance_q15 * pDst,
q15_t * pState);
/**
* @brief Q15 matrix and vector multiplication
* @param[in] pSrcMat points to the input matrix structure
* @param[in] pVec points to vector
* @param[out] pDst points to output vector
*/
void arm_mat_vec_mult_q15(
const arm_matrix_instance_q15 *pSrcMat,
const q15_t *pVec,
q15_t *pDst);
/**
* @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @param[in] pState points to the array for storing intermediate results
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_mult_fast_q15(
const arm_matrix_instance_q15 * pSrcA,
const arm_matrix_instance_q15 * pSrcB,
arm_matrix_instance_q15 * pDst,
q15_t * pState);
/**
* @brief Q31 matrix multiplication
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_mult_q31(
const arm_matrix_instance_q31 * pSrcA,
const arm_matrix_instance_q31 * pSrcB,
arm_matrix_instance_q31 * pDst);
/**
* @brief Q31 matrix multiplication
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @param[in] pState points to the array for storing intermediate results
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_mult_opt_q31(
const arm_matrix_instance_q31 * pSrcA,
const arm_matrix_instance_q31 * pSrcB,
arm_matrix_instance_q31 * pDst,
q31_t *pState);
/**
* @brief Q31 matrix and vector multiplication
* @param[in] pSrcMat points to the input matrix structure
* @param[in] pVec points to vector
* @param[out] pDst points to output vector
*/
void arm_mat_vec_mult_q31(
const arm_matrix_instance_q31 *pSrcMat,
const q31_t *pVec,
q31_t *pDst);
/**
* @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_mult_fast_q31(
const arm_matrix_instance_q31 * pSrcA,
const arm_matrix_instance_q31 * pSrcB,
arm_matrix_instance_q31 * pDst);
/**
* @brief Floating-point matrix subtraction
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_sub_f32(
const arm_matrix_instance_f32 * pSrcA,
const arm_matrix_instance_f32 * pSrcB,
arm_matrix_instance_f32 * pDst);
/**
* @brief Floating-point matrix subtraction
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_sub_f64(
const arm_matrix_instance_f64 * pSrcA,
const arm_matrix_instance_f64 * pSrcB,
arm_matrix_instance_f64 * pDst);
/**
* @brief Q15 matrix subtraction
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_sub_q15(
const arm_matrix_instance_q15 * pSrcA,
const arm_matrix_instance_q15 * pSrcB,
arm_matrix_instance_q15 * pDst);
/**
* @brief Q31 matrix subtraction
* @param[in] pSrcA points to the first input matrix structure
* @param[in] pSrcB points to the second input matrix structure
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_sub_q31(
const arm_matrix_instance_q31 * pSrcA,
const arm_matrix_instance_q31 * pSrcB,
arm_matrix_instance_q31 * pDst);
/**
* @brief Floating-point matrix scaling.
* @param[in] pSrc points to the input matrix
* @param[in] scale scale factor
* @param[out] pDst points to the output matrix
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_scale_f32(
const arm_matrix_instance_f32 * pSrc,
float32_t scale,
arm_matrix_instance_f32 * pDst);
/**
* @brief Q15 matrix scaling.
* @param[in] pSrc points to input matrix
* @param[in] scaleFract fractional portion of the scale factor
* @param[in] shift number of bits to shift the result by
* @param[out] pDst points to output matrix
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_scale_q15(
const arm_matrix_instance_q15 * pSrc,
q15_t scaleFract,
int32_t shift,
arm_matrix_instance_q15 * pDst);
/**
* @brief Q31 matrix scaling.
* @param[in] pSrc points to input matrix
* @param[in] scaleFract fractional portion of the scale factor
* @param[in] shift number of bits to shift the result by
* @param[out] pDst points to output matrix structure
* @return The function returns either
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
*/
arm_status arm_mat_scale_q31(
const arm_matrix_instance_q31 * pSrc,
q31_t scaleFract,
int32_t shift,
arm_matrix_instance_q31 * pDst);
/**
* @brief Q31 matrix initialization.
* @param[in,out] S points to an instance of the floating-point matrix structure.
* @param[in] nRows number of rows in the matrix.
* @param[in] nColumns number of columns in the matrix.
* @param[in] pData points to the matrix data array.
*/
void arm_mat_init_q31(
arm_matrix_instance_q31 * S,
uint16_t nRows,
uint16_t nColumns,
q31_t * pData);
/**
* @brief Q15 matrix initialization.
* @param[in,out] S points to an instance of the floating-point matrix structure.
* @param[in] nRows number of rows in the matrix.
* @param[in] nColumns number of columns in the matrix.
* @param[in] pData points to the matrix data array.
*/
void arm_mat_init_q15(
arm_matrix_instance_q15 * S,
uint16_t nRows,
uint16_t nColumns,
q15_t * pData);
/**
* @brief Floating-point matrix initialization.
* @param[in,out] S points to an instance of the floating-point matrix structure.
* @param[in] nRows number of rows in the matrix.
* @param[in] nColumns number of columns in the matrix.
* @param[in] pData points to the matrix data array.
*/
void arm_mat_init_f32(
arm_matrix_instance_f32 * S,
uint16_t nRows,
uint16_t nColumns,
float32_t * pData);
/**
* @brief Floating-point matrix inverse.
* @param[in] src points to the instance of the input floating-point matrix structure.
* @param[out] dst points to the instance of the output floating-point matrix structure.
* @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
* If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
*/
arm_status arm_mat_inverse_f32(
const arm_matrix_instance_f32 * src,
arm_matrix_instance_f32 * dst);
/**
* @brief Floating-point matrix inverse.
* @param[in] src points to the instance of the input floating-point matrix structure.
* @param[out] dst points to the instance of the output floating-point matrix structure.
* @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
* If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
*/
arm_status arm_mat_inverse_f64(
const arm_matrix_instance_f64 * src,
arm_matrix_instance_f64 * dst);
/**
* @brief Floating-point matrix inverse.
* @param[in] src points to the instance of the input floating-point matrix structure.
* @param[out] dst points to the instance of the output floating-point matrix structure.
* @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
* If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
*/
arm_status arm_mat_cmplx_inv_f32(
const arm_matrix_instance_f32 * src,
arm_matrix_instance_f32 * dst);
/**
* @brief Floating-point Cholesky decomposition of Symmetric Positive Definite Matrix.
* @param[in] src points to the instance of the input floating-point matrix structure.
* @param[out] dst points to the instance of the output floating-point matrix structure.
* @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
* If the input matrix does not have a decomposition, then the algorithm terminates and returns error status ARM_MATH_DECOMPOSITION_FAILURE.
* If the matrix is ill conditioned or only semi-definite, then it is better using the LDL^t decomposition.
* The decomposition is returning a lower triangular matrix.
*/
arm_status arm_mat_cholesky_f64(
const arm_matrix_instance_f64 * src,
arm_matrix_instance_f64 * dst);
/**
* @brief Floating-point Cholesky decomposition of Symmetric Positive Definite Matrix.
* @param[in] src points to the instance of the input floating-point matrix structure.
* @param[out] dst points to the instance of the output floating-point matrix structure.
* @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
* If the input matrix does not have a decomposition, then the algorithm terminates and returns error status ARM_MATH_DECOMPOSITION_FAILURE.
* If the matrix is ill conditioned or only semi-definite, then it is better using the LDL^t decomposition.
* The decomposition is returning a lower triangular matrix.
*/
arm_status arm_mat_cholesky_f32(
const arm_matrix_instance_f32 * src,
arm_matrix_instance_f32 * dst);
/**
* @brief Solve UT . X = A where UT is an upper triangular matrix
* @param[in] ut The upper triangular matrix
* @param[in] a The matrix a
* @param[out] dst The solution X of UT . X = A
* @return The function returns ARM_MATH_SINGULAR, if the system can't be solved.
*/
arm_status arm_mat_solve_upper_triangular_f32(
const arm_matrix_instance_f32 * ut,
const arm_matrix_instance_f32 * a,
arm_matrix_instance_f32 * dst);
/**
* @brief Solve LT . X = A where LT is a lower triangular matrix
* @param[in] lt The lower triangular matrix
* @param[in] a The matrix a
* @param[out] dst The solution X of LT . X = A
* @return The function returns ARM_MATH_SINGULAR, if the system can't be solved.
*/
arm_status arm_mat_solve_lower_triangular_f32(
const arm_matrix_instance_f32 * lt,
const arm_matrix_instance_f32 * a,
arm_matrix_instance_f32 * dst);
/**
* @brief Solve UT . X = A where UT is an upper triangular matrix
* @param[in] ut The upper triangular matrix
* @param[in] a The matrix a
* @param[out] dst The solution X of UT . X = A
* @return The function returns ARM_MATH_SINGULAR, if the system can't be solved.
*/
arm_status arm_mat_solve_upper_triangular_f64(
const arm_matrix_instance_f64 * ut,
const arm_matrix_instance_f64 * a,
arm_matrix_instance_f64 * dst);
/**
* @brief Solve LT . X = A where LT is a lower triangular matrix
* @param[in] lt The lower triangular matrix
* @param[in] a The matrix a
* @param[out] dst The solution X of LT . X = A
* @return The function returns ARM_MATH_SINGULAR, if the system can't be solved.
*/
arm_status arm_mat_solve_lower_triangular_f64(
const arm_matrix_instance_f64 * lt,
const arm_matrix_instance_f64 * a,
arm_matrix_instance_f64 * dst);
/**
* @brief Floating-point LDL decomposition of Symmetric Positive Semi-Definite Matrix.
* @param[in] src points to the instance of the input floating-point matrix structure.
* @param[out] l points to the instance of the output floating-point triangular matrix structure.
* @param[out] d points to the instance of the output floating-point diagonal matrix structure.
* @param[out] p points to the instance of the output floating-point permutation vector.
* @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
* If the input matrix does not have a decomposition, then the algorithm terminates and returns error status ARM_MATH_DECOMPOSITION_FAILURE.
* The decomposition is returning a lower triangular matrix.
*/
arm_status arm_mat_ldlt_f32(
const arm_matrix_instance_f32 * src,
arm_matrix_instance_f32 * l,
arm_matrix_instance_f32 * d,
uint16_t * pp);
/**
* @brief Floating-point LDL decomposition of Symmetric Positive Semi-Definite Matrix.
* @param[in] src points to the instance of the input floating-point matrix structure.
* @param[out] l points to the instance of the output floating-point triangular matrix structure.
* @param[out] d points to the instance of the output floating-point diagonal matrix structure.
* @param[out] p points to the instance of the output floating-point permutation vector.
* @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
* If the input matrix does not have a decomposition, then the algorithm terminates and returns error status ARM_MATH_DECOMPOSITION_FAILURE.
* The decomposition is returning a lower triangular matrix.
*/
arm_status arm_mat_ldlt_f64(
const arm_matrix_instance_f64 * src,
arm_matrix_instance_f64 * l,
arm_matrix_instance_f64 * d,
uint16_t * pp);
#ifdef __cplusplus
}
#endif
#endif /* ifndef _MATRIX_FUNCTIONS_H_ */
@@ -0,0 +1,640 @@
/******************************************************************************
* @file matrix_utils.h
* @brief Public header file for CMSIS DSP Library
* @version V1.11.0
* @date 30 May 2022
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2022 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _MATRIX_UTILS_H_
#define _MATRIX_UTILS_H_
#include "arm_math_types.h"
#include "arm_math_memory.h"
#include "dsp/none.h"
#include "dsp/utils.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define ELEM(A,ROW,COL) &((A)->pData[(A)->numCols* (ROW) + (COL)])
#define SCALE_COL_T(T,CAST,A,ROW,v,i) \
{ \
int32_t w; \
T *data = (A)->pData; \
const int32_t numCols = (A)->numCols; \
const int32_t nb = (A)->numRows - ROW;\
\
data += i + numCols * (ROW); \
\
for(w=0;w < nb; w++) \
{ \
*data *= CAST v; \
data += numCols; \
} \
}
#define COPY_COL_T(T,A,ROW,COL,DST) \
{ \
uint32_t row; \
T *pb=DST; \
T *pa = (A)->pData + ROW * (A)->numCols + COL;\
for(row = ROW; row < (A)->numRows; row ++) \
{ \
*pb++ = *pa; \
pa += (A)->numCols; \
} \
}
#if defined(ARM_FLOAT16_SUPPORTED)
#if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
#define SWAP_ROWS_F16(A,COL,i,j) \
{ \
int cnt = ((A)->numCols)-(COL); \
int32_t w; \
float16_t *data = (A)->pData; \
const int32_t numCols = (A)->numCols; \
\
for(w=(COL);w < numCols; w+=8) \
{ \
f16x8_t tmpa,tmpb; \
mve_pred16_t p0 = vctp16q(cnt); \
\
tmpa=vldrhq_z_f16(&data[i*numCols + w],p0);\
tmpb=vldrhq_z_f16(&data[j*numCols + w],p0);\
\
vstrhq_p(&data[i*numCols + w], tmpb, p0); \
vstrhq_p(&data[j*numCols + w], tmpa, p0); \
\
cnt -= 8; \
} \
}
#define SCALE_ROW_F16(A,COL,v,i) \
{ \
int cnt = ((A)->numCols)-(COL); \
int32_t w; \
float16_t *data = (A)->pData; \
const int32_t numCols = (A)->numCols; \
\
for(w=(COL);w < numCols; w+=8) \
{ \
f16x8_t tmpa; \
mve_pred16_t p0 = vctp16q(cnt); \
tmpa = vldrhq_z_f16(&data[i*numCols + w],p0);\
tmpa = vmulq_n_f16(tmpa,(_Float16)v); \
vstrhq_p(&data[i*numCols + w], tmpa, p0); \
cnt -= 8; \
} \
\
}
#define MAC_ROW_F16(COL,A,i,v,B,j) \
{ \
int cnt = ((A)->numCols)-(COL); \
int32_t w; \
float16_t *dataA = (A)->pData; \
float16_t *dataB = (B)->pData; \
const int32_t numCols = (A)->numCols; \
\
for(w=(COL);w < numCols; w+=8) \
{ \
f16x8_t tmpa,tmpb; \
mve_pred16_t p0 = vctp16q(cnt); \
tmpa = vldrhq_z_f16(&dataA[i*numCols + w],p0);\
tmpb = vldrhq_z_f16(&dataB[j*numCols + w],p0);\
tmpa = vfmaq_n_f16(tmpa,tmpb,v); \
vstrhq_p(&dataA[i*numCols + w], tmpa, p0); \
cnt -= 8; \
} \
\
}
#define MAS_ROW_F16(COL,A,i,v,B,j) \
{ \
int cnt = ((A)->numCols)-(COL); \
int32_t w; \
float16_t *dataA = (A)->pData; \
float16_t *dataB = (B)->pData; \
const int32_t numCols = (A)->numCols; \
f16x8_t vec=vdupq_n_f16(v); \
\
for(w=(COL);w < numCols; w+=8) \
{ \
f16x8_t tmpa,tmpb; \
mve_pred16_t p0 = vctp16q(cnt); \
tmpa = vldrhq_z_f16(&dataA[i*numCols + w],p0);\
tmpb = vldrhq_z_f16(&dataB[j*numCols + w],p0);\
tmpa = vfmsq_f16(tmpa,tmpb,vec); \
vstrhq_p(&dataA[i*numCols + w], tmpa, p0); \
cnt -= 8; \
} \
\
}
#else
#define SWAP_ROWS_F16(A,COL,i,j) \
{ \
int32_t w; \
float16_t *dataI = (A)->pData; \
float16_t *dataJ = (A)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols-(COL); \
\
dataI += i*numCols + (COL); \
dataJ += j*numCols + (COL); \
\
for(w=0;w < nb; w++) \
{ \
float16_t tmp; \
tmp = *dataI; \
*dataI++ = *dataJ; \
*dataJ++ = tmp; \
} \
}
#define SCALE_ROW_F16(A,COL,v,i) \
{ \
int32_t w; \
float16_t *data = (A)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols-(COL); \
\
data += i*numCols + (COL); \
\
for(w=0;w < nb; w++) \
{ \
*data++ *= (_Float16)v; \
} \
}
#define MAC_ROW_F16(COL,A,i,v,B,j) \
{ \
int32_t w; \
float16_t *dataA = (A)->pData; \
float16_t *dataB = (B)->pData; \
const int32_t numCols = (A)->numCols; \
const int32_t nb = numCols-(COL); \
\
dataA += i*numCols + (COL); \
dataB += j*numCols + (COL); \
\
for(w=0;w < nb; w++) \
{ \
*dataA++ += (_Float16)v * (_Float16)*dataB++;\
} \
}
#define MAS_ROW_F16(COL,A,i,v,B,j) \
{ \
int32_t w; \
float16_t *dataA = (A)->pData; \
float16_t *dataB = (B)->pData; \
const int32_t numCols = (A)->numCols; \
const int32_t nb = numCols-(COL); \
\
dataA += i*numCols + (COL); \
dataB += j*numCols + (COL); \
\
for(w=0;w < nb; w++) \
{ \
*dataA++ -= (_Float16)v * (_Float16)*dataB++;\
} \
}
#endif /*defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)*/
/* Functions with only a scalar version */
#define COPY_COL_F16(A,ROW,COL,DST) \
COPY_COL_T(float16_t,A,ROW,COL,DST)
#define SCALE_COL_F16(A,ROW,v,i) \
SCALE_COL_T(float16_t,(_Float16),A,ROW,v,i)
#endif /* defined(ARM_FLOAT16_SUPPORTED)*/
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
#define SWAP_ROWS_F32(A,COL,i,j) \
{ \
int cnt = ((A)->numCols)-(COL); \
float32_t *data = (A)->pData; \
const int32_t numCols = (A)->numCols; \
int32_t w; \
\
for(w=(COL);w < numCols; w+=4) \
{ \
f32x4_t tmpa,tmpb; \
mve_pred16_t p0 = vctp32q(cnt); \
\
tmpa=vldrwq_z_f32(&data[i*numCols + w],p0);\
tmpb=vldrwq_z_f32(&data[j*numCols + w],p0);\
\
vstrwq_p(&data[i*numCols + w], tmpb, p0); \
vstrwq_p(&data[j*numCols + w], tmpa, p0); \
\
cnt -= 4; \
} \
}
#define MAC_ROW_F32(COL,A,i,v,B,j) \
{ \
int cnt = ((A)->numCols)-(COL); \
float32_t *dataA = (A)->pData; \
float32_t *dataB = (B)->pData; \
const int32_t numCols = (A)->numCols; \
int32_t w; \
\
for(w=(COL);w < numCols; w+=4) \
{ \
f32x4_t tmpa,tmpb; \
mve_pred16_t p0 = vctp32q(cnt); \
tmpa = vldrwq_z_f32(&dataA[i*numCols + w],p0);\
tmpb = vldrwq_z_f32(&dataB[j*numCols + w],p0);\
tmpa = vfmaq_n_f32(tmpa,tmpb,v); \
vstrwq_p(&dataA[i*numCols + w], tmpa, p0); \
cnt -= 4; \
} \
\
}
#define MAS_ROW_F32(COL,A,i,v,B,j) \
{ \
int cnt = ((A)->numCols)-(COL); \
float32_t *dataA = (A)->pData; \
float32_t *dataB = (B)->pData; \
const int32_t numCols = (A)->numCols; \
int32_t w; \
f32x4_t vec=vdupq_n_f32(v); \
\
for(w=(COL);w < numCols; w+=4) \
{ \
f32x4_t tmpa,tmpb; \
mve_pred16_t p0 = vctp32q(cnt); \
tmpa = vldrwq_z_f32(&dataA[i*numCols + w],p0);\
tmpb = vldrwq_z_f32(&dataB[j*numCols + w],p0);\
tmpa = vfmsq_f32(tmpa,tmpb,vec); \
vstrwq_p(&dataA[i*numCols + w], tmpa, p0); \
cnt -= 4; \
} \
\
}
#define SCALE_ROW_F32(A,COL,v,i) \
{ \
int cnt = ((A)->numCols)-(COL); \
float32_t *data = (A)->pData; \
const int32_t numCols = (A)->numCols; \
int32_t w; \
\
for(w=(COL);w < numCols; w+=4) \
{ \
f32x4_t tmpa; \
mve_pred16_t p0 = vctp32q(cnt); \
tmpa = vldrwq_z_f32(&data[i*numCols + w],p0);\
tmpa = vmulq_n_f32(tmpa,v); \
vstrwq_p(&data[i*numCols + w], tmpa, p0); \
cnt -= 4; \
} \
\
}
#elif defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
#define SWAP_ROWS_F32(A,COL,i,j) \
{ \
int32_t w; \
float32_t *dataI = (A)->pData; \
float32_t *dataJ = (A)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols - COL; \
\
dataI += i*numCols + (COL); \
dataJ += j*numCols + (COL); \
\
float32_t tmp; \
\
for(w=0;w < nb; w++) \
{ \
tmp = *dataI; \
*dataI++ = *dataJ; \
*dataJ++ = tmp; \
} \
}
#define MAC_ROW_F32(COL,A,i,v,B,j) \
{ \
float32_t *dataA = (A)->pData; \
float32_t *dataB = (B)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols - (COL); \
int32_t nbElems; \
f32x4_t vec = vdupq_n_f32(v); \
\
nbElems = nb >> 2; \
\
dataA += i*numCols + (COL); \
dataB += j*numCols + (COL); \
\
while(nbElems>0) \
{ \
f32x4_t tmpa,tmpb; \
tmpa = vld1q_f32(dataA,p0); \
tmpb = vld1q_f32(dataB,p0); \
tmpa = vmlaq_f32(tmpa,tmpb,vec);\
vst1q_f32(dataA, tmpa, p0); \
nbElems--; \
dataA += 4; \
dataB += 4; \
} \
\
nbElems = nb & 3; \
while(nbElems > 0) \
{ \
*dataA++ += v* *dataB++; \
nbElems--; \
} \
}
#define MAS_ROW_F32(COL,A,i,v,B,j) \
{ \
float32_t *dataA = (A)->pData; \
float32_t *dataB = (B)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols - (COL); \
int32_t nbElems; \
f32x4_t vec = vdupq_n_f32(v); \
\
nbElems = nb >> 2; \
\
dataA += i*numCols + (COL); \
dataB += j*numCols + (COL); \
\
while(nbElems>0) \
{ \
f32x4_t tmpa,tmpb; \
tmpa = vld1q_f32(dataA); \
tmpb = vld1q_f32(dataB); \
tmpa = vmlsq_f32(tmpa,tmpb,vec);\
vst1q_f32(dataA, tmpa); \
nbElems--; \
dataA += 4; \
dataB += 4; \
} \
\
nbElems = nb & 3; \
while(nbElems > 0) \
{ \
*dataA++ -= v* *dataB++; \
nbElems--; \
} \
}
#define SCALE_ROW_F32(A,COL,v,i) \
{ \
float32_t *data = (A)->pData; \
const int32_t numCols = (A)->numCols; \
const int32_t nb = numCols - (COL); \
int32_t nbElems; \
f32x4_t vec = vdupq_n_f32(v); \
\
nbElems = nb >> 2; \
\
data += i*numCols + (COL); \
while(nbElems>0) \
{ \
f32x4_t tmpa; \
tmpa = vld1q_f32(data); \
tmpa = vmulq_f32(tmpa,vec); \
vst1q_f32(data, tmpa); \
data += 4; \
nbElems --; \
} \
\
nbElems = nb & 3; \
while(nbElems > 0) \
{ \
*data++ *= v; \
nbElems--; \
} \
\
}
#else
#define SWAP_ROWS_F32(A,COL,i,j) \
{ \
int32_t w; \
float32_t tmp; \
float32_t *dataI = (A)->pData; \
float32_t *dataJ = (A)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols - COL; \
\
dataI += i*numCols + (COL); \
dataJ += j*numCols + (COL); \
\
\
for(w=0;w < nb; w++) \
{ \
tmp = *dataI; \
*dataI++ = *dataJ; \
*dataJ++ = tmp; \
} \
}
#define SCALE_ROW_F32(A,COL,v,i) \
{ \
int32_t w; \
float32_t *data = (A)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols - COL; \
\
data += i*numCols + (COL); \
\
for(w=0;w < nb; w++) \
{ \
*data++ *= v; \
} \
}
#define MAC_ROW_F32(COL,A,i,v,B,j) \
{ \
int32_t w; \
float32_t *dataA = (A)->pData; \
float32_t *dataB = (B)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols-(COL); \
\
dataA = dataA + i*numCols + (COL); \
dataB = dataB + j*numCols + (COL); \
\
for(w=0;w < nb; w++) \
{ \
*dataA++ += v* *dataB++; \
} \
}
#define MAS_ROW_F32(COL,A,i,v,B,j) \
{ \
int32_t w; \
float32_t *dataA = (A)->pData; \
float32_t *dataB = (B)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols-(COL); \
\
dataA = dataA + i*numCols + (COL); \
dataB = dataB + j*numCols + (COL); \
\
for(w=0;w < nb; w++) \
{ \
*dataA++ -= v* *dataB++; \
} \
}
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
/* Functions with only a scalar version */
#define COPY_COL_F32(A,ROW,COL,DST) \
COPY_COL_T(float32_t,A,ROW,COL,DST)
#define COPY_COL_F64(A,ROW,COL,DST) \
COPY_COL_T(float64_t,A,ROW,COL,DST)
#define SWAP_COLS_F32(A,COL,i,j) \
{ \
int32_t w; \
float32_t *data = (A)->pData; \
const int32_t numCols = (A)->numCols; \
for(w=(COL);w < numCols; w++) \
{ \
float32_t tmp; \
tmp = data[w*numCols + i]; \
data[w*numCols + i] = data[w*numCols + j];\
data[w*numCols + j] = tmp; \
} \
}
#define SCALE_COL_F32(A,ROW,v,i) \
SCALE_COL_T(float32_t,,A,ROW,v,i)
#define SWAP_ROWS_F64(A,COL,i,j) \
{ \
int32_t w; \
float64_t *dataI = (A)->pData; \
float64_t *dataJ = (A)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols-(COL); \
\
dataI += i*numCols + (COL); \
dataJ += j*numCols + (COL); \
\
for(w=0;w < nb; w++) \
{ \
float64_t tmp; \
tmp = *dataI; \
*dataI++ = *dataJ; \
*dataJ++ = tmp; \
} \
}
#define SWAP_COLS_F64(A,COL,i,j) \
{ \
int32_t w; \
float64_t *data = (A)->pData; \
const int32_t numCols = (A)->numCols; \
for(w=(COL);w < numCols; w++) \
{ \
float64_t tmp; \
tmp = data[w*numCols + i]; \
data[w*numCols + i] = data[w*numCols + j];\
data[w*numCols + j] = tmp; \
} \
}
#define SCALE_ROW_F64(A,COL,v,i) \
{ \
int32_t w; \
float64_t *data = (A)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols-(COL); \
\
data += i*numCols + (COL); \
\
for(w=0;w < nb; w++) \
{ \
*data++ *= v; \
} \
}
#define SCALE_COL_F64(A,ROW,v,i) \
SCALE_COL_T(float64_t,,A,ROW,v,i)
#define MAC_ROW_F64(COL,A,i,v,B,j) \
{ \
int32_t w; \
float64_t *dataA = (A)->pData; \
float64_t *dataB = (B)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols-(COL); \
\
dataA += i*numCols + (COL); \
dataB += j*numCols + (COL); \
\
for(w=0;w < nb; w++) \
{ \
*dataA++ += v* *dataB++; \
} \
}
#define MAS_ROW_F64(COL,A,i,v,B,j) \
{ \
int32_t w; \
float64_t *dataA = (A)->pData; \
float64_t *dataB = (B)->pData; \
const int32_t numCols = (A)->numCols;\
const int32_t nb = numCols-(COL); \
\
dataA += i*numCols + (COL); \
dataB += j*numCols + (COL); \
\
for(w=0;w < nb; w++) \
{ \
*dataA++ -= v* *dataB++; \
} \
}
#ifdef __cplusplus
}
#endif
#endif /* ifndef _MATRIX_UTILS_H_ */
@@ -0,0 +1,576 @@
/******************************************************************************
* @file none.h
* @brief Intrinsincs when no DSP extension available
* @version V1.9.0
* @date 20. July 2020
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
Definitions in this file are allowing to reuse some versions of the
CMSIS-DSP to build on a core (M0 for instance) or a host where
DSP extension are not available.
Ideally a pure C version should have been used instead.
But those are not always available or use a restricted set
of intrinsics.
*/
#ifndef _NONE_H_
#define _NONE_H_
#include "arm_math_types.h"
#ifdef __cplusplus
extern "C"
{
#endif
/*
Normally those kind of definitions are in a compiler file
in Core or Core_A.
But for MSVC compiler it is a bit special. The goal is very specific
to CMSIS-DSP and only to allow the use of this library from other
systems like Python or Matlab.
MSVC is not going to be used to cross-compile to ARM. So, having a MSVC
compiler file in Core or Core_A would not make sense.
*/
#if defined ( _MSC_VER ) || defined(__GNUC_PYTHON__) || defined(__APPLE_CC__)
__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t data)
{
if (data == 0U) { return 32U; }
uint32_t count = 0U;
uint32_t mask = 0x80000000U;
while ((data & mask) == 0U)
{
count += 1U;
mask = mask >> 1U;
}
return count;
}
__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat)
{
if ((sat >= 1U) && (sat <= 32U))
{
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
const int32_t min = -1 - max ;
if (val > max)
{
return max;
}
else if (val < min)
{
return min;
}
}
return val;
}
__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat)
{
if (sat <= 31U)
{
const uint32_t max = ((1U << sat) - 1U);
if (val > (int32_t)max)
{
return max;
}
else if (val < 0)
{
return 0U;
}
}
return (uint32_t)val;
}
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] op1 Value to rotate
\param [in] op2 Number of Bits to rotate
\return Rotated value
*/
__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
op2 %= 32U;
if (op2 == 0U)
{
return op1;
}
return (op1 >> op2) | (op1 << (32U - op2));
}
#endif
/**
* @brief Clips Q63 to Q31 values.
*/
__STATIC_FORCEINLINE q31_t clip_q63_to_q31(
q63_t x)
{
return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x;
}
/**
* @brief Clips Q63 to Q15 values.
*/
__STATIC_FORCEINLINE q15_t clip_q63_to_q15(
q63_t x)
{
return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15);
}
/**
* @brief Clips Q31 to Q7 values.
*/
__STATIC_FORCEINLINE q7_t clip_q31_to_q7(
q31_t x)
{
return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ?
((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x;
}
/**
* @brief Clips Q31 to Q15 values.
*/
__STATIC_FORCEINLINE q15_t clip_q31_to_q15(
q31_t x)
{
return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ?
((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x;
}
/**
* @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format.
*/
__STATIC_FORCEINLINE q63_t mult32x64(
q63_t x,
q31_t y)
{
return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) +
(((q63_t) (x >> 32) * y) ) );
}
/* SMMLAR */
#define multAcc_32x32_keep32_R(a, x, y) \
a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32)
/* SMMLSR */
#define multSub_32x32_keep32_R(a, x, y) \
a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32)
/* SMMULR */
#define mult_32x32_keep32_R(a, x, y) \
a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32)
/* SMMLA */
#define multAcc_32x32_keep32(a, x, y) \
a += (q31_t) (((q63_t) x * y) >> 32)
/* SMMLS */
#define multSub_32x32_keep32(a, x, y) \
a -= (q31_t) (((q63_t) x * y) >> 32)
/* SMMUL */
#define mult_32x32_keep32(a, x, y) \
a = (q31_t) (((q63_t) x * y ) >> 32)
#ifndef ARM_MATH_DSP
/**
* @brief definition to pack two 16 bit values.
*/
#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \
(((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) )
#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \
(((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) )
#endif
/**
* @brief definition to pack four 8 bit values.
*/
#ifndef ARM_MATH_BIG_ENDIAN
#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \
(((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \
(((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \
(((int32_t)(v3) << 24) & (int32_t)0xFF000000) )
#else
#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \
(((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \
(((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \
(((int32_t)(v0) << 24) & (int32_t)0xFF000000) )
#endif
/*
* @brief C custom defined intrinsic functions
*/
#if !defined (ARM_MATH_DSP)
/*
* @brief C custom defined QADD8
*/
__STATIC_FORCEINLINE uint32_t __QADD8(
uint32_t x,
uint32_t y)
{
q31_t r, s, t, u;
r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF;
u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF;
return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r )));
}
/*
* @brief C custom defined QSUB8
*/
__STATIC_FORCEINLINE uint32_t __QSUB8(
uint32_t x,
uint32_t y)
{
q31_t r, s, t, u;
r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF;
u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF;
return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r )));
}
/*
* @brief C custom defined QADD16
*/
__STATIC_FORCEINLINE uint32_t __QADD16(
uint32_t x,
uint32_t y)
{
/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */
q31_t r = 0, s = 0;
r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF;
return ((uint32_t)((s << 16) | (r )));
}
/*
* @brief C custom defined SHADD16
*/
__STATIC_FORCEINLINE uint32_t __SHADD16(
uint32_t x,
uint32_t y)
{
q31_t r, s;
r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
return ((uint32_t)((s << 16) | (r )));
}
/*
* @brief C custom defined QSUB16
*/
__STATIC_FORCEINLINE uint32_t __QSUB16(
uint32_t x,
uint32_t y)
{
q31_t r, s;
r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF;
return ((uint32_t)((s << 16) | (r )));
}
/*
* @brief C custom defined SHSUB16
*/
__STATIC_FORCEINLINE uint32_t __SHSUB16(
uint32_t x,
uint32_t y)
{
q31_t r, s;
r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
return ((uint32_t)((s << 16) | (r )));
}
/*
* @brief C custom defined QASX
*/
__STATIC_FORCEINLINE uint32_t __QASX(
uint32_t x,
uint32_t y)
{
q31_t r, s;
r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF;
s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
return ((uint32_t)((s << 16) | (r )));
}
/*
* @brief C custom defined SHASX
*/
__STATIC_FORCEINLINE uint32_t __SHASX(
uint32_t x,
uint32_t y)
{
q31_t r, s;
r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
return ((uint32_t)((s << 16) | (r )));
}
/*
* @brief C custom defined QSAX
*/
__STATIC_FORCEINLINE uint32_t __QSAX(
uint32_t x,
uint32_t y)
{
q31_t r, s;
r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF;
s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
return ((uint32_t)((s << 16) | (r )));
}
/*
* @brief C custom defined SHSAX
*/
__STATIC_FORCEINLINE uint32_t __SHSAX(
uint32_t x,
uint32_t y)
{
q31_t r, s;
r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
return ((uint32_t)((s << 16) | (r )));
}
/*
* @brief C custom defined SMUSDX
*/
__STATIC_FORCEINLINE uint32_t __SMUSDX(
uint32_t x,
uint32_t y)
{
return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) -
((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) ));
}
/*
* @brief C custom defined SMUADX
*/
__STATIC_FORCEINLINE uint32_t __SMUADX(
uint32_t x,
uint32_t y)
{
return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) +
((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) ));
}
/*
* @brief C custom defined QADD
*/
__STATIC_FORCEINLINE int32_t __QADD(
int32_t x,
int32_t y)
{
return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y)));
}
/*
* @brief C custom defined QSUB
*/
__STATIC_FORCEINLINE int32_t __QSUB(
int32_t x,
int32_t y)
{
return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y)));
}
/*
* @brief C custom defined SMLAD
*/
__STATIC_FORCEINLINE uint32_t __SMLAD(
uint32_t x,
uint32_t y,
uint32_t sum)
{
return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) +
( ((q31_t)sum ) ) ));
}
/*
* @brief C custom defined SMLADX
*/
__STATIC_FORCEINLINE uint32_t __SMLADX(
uint32_t x,
uint32_t y,
uint32_t sum)
{
return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) +
((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) +
( ((q31_t)sum ) ) ));
}
/*
* @brief C custom defined SMLSDX
*/
__STATIC_FORCEINLINE uint32_t __SMLSDX(
uint32_t x,
uint32_t y,
uint32_t sum)
{
return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) -
((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) +
( ((q31_t)sum ) ) ));
}
/*
* @brief C custom defined SMLALD
*/
__STATIC_FORCEINLINE uint64_t __SMLALD(
uint32_t x,
uint32_t y,
uint64_t sum)
{
/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */
return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) +
( ((q63_t)sum ) ) ));
}
/*
* @brief C custom defined SMLALDX
*/
__STATIC_FORCEINLINE uint64_t __SMLALDX(
uint32_t x,
uint32_t y,
uint64_t sum)
{
/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */
return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) +
((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) +
( ((q63_t)sum ) ) ));
}
/*
* @brief C custom defined SMUAD
*/
__STATIC_FORCEINLINE uint32_t __SMUAD(
uint32_t x,
uint32_t y)
{
return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) ));
}
/*
* @brief C custom defined SMUSD
*/
__STATIC_FORCEINLINE uint32_t __SMUSD(
uint32_t x,
uint32_t y)
{
return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) -
((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) ));
}
/*
* @brief C custom defined SXTB16
*/
__STATIC_FORCEINLINE uint32_t __SXTB16(
uint32_t x)
{
return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) |
((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) ));
}
/*
* @brief C custom defined SMMLA
*/
__STATIC_FORCEINLINE int32_t __SMMLA(
int32_t x,
int32_t y,
int32_t sum)
{
return (sum + (int32_t) (((int64_t) x * y) >> 32));
}
#endif /* !defined (ARM_MATH_DSP) */
#ifdef __cplusplus
}
#endif
#endif /* ifndef _TRANSFORM_FUNCTIONS_H_ */
@@ -0,0 +1,977 @@
/******************************************************************************
* @file statistics_functions.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _STATISTICS_FUNCTIONS_H_
#define _STATISTICS_FUNCTIONS_H_
#include "arm_math_types.h"
#include "arm_math_memory.h"
#include "dsp/none.h"
#include "dsp/utils.h"
#include "dsp/basic_math_functions.h"
#include "dsp/fast_math_functions.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @defgroup groupStats Statistics Functions
*/
/**
* @brief Computation of the LogSumExp
*
* In probabilistic computations, the dynamic of the probability values can be very
* wide because they come from gaussian functions.
* To avoid underflow and overflow issues, the values are represented by their log.
* In this representation, multiplying the original exp values is easy : their logs are added.
* But adding the original exp values is requiring some special handling and it is the
* goal of the LogSumExp function.
*
* If the values are x1...xn, the function is computing:
*
* ln(exp(x1) + ... + exp(xn)) and the computation is done in such a way that
* rounding issues are minimised.
*
* The max xm of the values is extracted and the function is computing:
* xm + ln(exp(x1 - xm) + ... + exp(xn - xm))
*
* @param[in] *in Pointer to an array of input values.
* @param[in] blockSize Number of samples in the input array.
* @return LogSumExp
*
*/
float32_t arm_logsumexp_f32(const float32_t *in, uint32_t blockSize);
/**
* @brief Dot product with log arithmetic
*
* Vectors are containing the log of the samples
*
* @param[in] pSrcA points to the first input vector
* @param[in] pSrcB points to the second input vector
* @param[in] blockSize number of samples in each vector
* @param[in] pTmpBuffer temporary buffer of length blockSize
* @return The log of the dot product .
*
*/
float32_t arm_logsumexp_dot_prod_f32(const float32_t * pSrcA,
const float32_t * pSrcB,
uint32_t blockSize,
float32_t *pTmpBuffer);
/**
* @brief Entropy
*
* @param[in] pSrcA Array of input values.
* @param[in] blockSize Number of samples in the input array.
* @return Entropy -Sum(p ln p)
*
*/
float32_t arm_entropy_f32(const float32_t * pSrcA,uint32_t blockSize);
/**
* @brief Entropy
*
* @param[in] pSrcA Array of input values.
* @param[in] blockSize Number of samples in the input array.
* @return Entropy -Sum(p ln p)
*
*/
float64_t arm_entropy_f64(const float64_t * pSrcA, uint32_t blockSize);
/**
* @brief Kullback-Leibler
*
* @param[in] pSrcA Pointer to an array of input values for probability distribution A.
* @param[in] pSrcB Pointer to an array of input values for probability distribution B.
* @param[in] blockSize Number of samples in the input array.
* @return Kullback-Leibler Divergence D(A || B)
*
*/
float32_t arm_kullback_leibler_f32(const float32_t * pSrcA
,const float32_t * pSrcB
,uint32_t blockSize);
/**
* @brief Kullback-Leibler
*
* @param[in] pSrcA Pointer to an array of input values for probability distribution A.
* @param[in] pSrcB Pointer to an array of input values for probability distribution B.
* @param[in] blockSize Number of samples in the input array.
* @return Kullback-Leibler Divergence D(A || B)
*
*/
float64_t arm_kullback_leibler_f64(const float64_t * pSrcA,
const float64_t * pSrcB,
uint32_t blockSize);
/**
* @brief Sum of the squares of the elements of a Q31 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_power_q31(
const q31_t * pSrc,
uint32_t blockSize,
q63_t * pResult);
/**
* @brief Sum of the squares of the elements of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_power_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult);
/**
* @brief Sum of the squares of the elements of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_power_f64(
const float64_t * pSrc,
uint32_t blockSize,
float64_t * pResult);
/**
* @brief Sum of the squares of the elements of a Q15 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_power_q15(
const q15_t * pSrc,
uint32_t blockSize,
q63_t * pResult);
/**
* @brief Sum of the squares of the elements of a Q7 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_power_q7(
const q7_t * pSrc,
uint32_t blockSize,
q31_t * pResult);
/**
* @brief Mean value of a Q7 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_mean_q7(
const q7_t * pSrc,
uint32_t blockSize,
q7_t * pResult);
/**
* @brief Mean value of a Q15 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_mean_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult);
/**
* @brief Mean value of a Q31 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_mean_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult);
/**
* @brief Mean value of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_mean_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult);
/**
* @brief Mean value of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_mean_f64(
const float64_t * pSrc,
uint32_t blockSize,
float64_t * pResult);
/**
* @brief Variance of the elements of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_var_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult);
/**
* @brief Variance of the elements of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_var_f64(
const float64_t * pSrc,
uint32_t blockSize,
float64_t * pResult);
/**
* @brief Variance of the elements of a Q31 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_var_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult);
/**
* @brief Variance of the elements of a Q15 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_var_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult);
/**
* @brief Root Mean Square of the elements of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_rms_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult);
/**
* @brief Root Mean Square of the elements of a Q31 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_rms_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult);
/**
* @brief Root Mean Square of the elements of a Q15 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_rms_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult);
/**
* @brief Standard deviation of the elements of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_std_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult);
/**
* @brief Standard deviation of the elements of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_std_f64(
const float64_t * pSrc,
uint32_t blockSize,
float64_t * pResult);
/**
* @brief Standard deviation of the elements of a Q31 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_std_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult);
/**
* @brief Standard deviation of the elements of a Q15 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output value.
*/
void arm_std_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult);
/**
* @brief Minimum value of a Q7 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] result is output pointer
* @param[in] index is the array index of the minimum value in the input buffer.
*/
void arm_min_q7(
const q7_t * pSrc,
uint32_t blockSize,
q7_t * result,
uint32_t * index);
/**
* @brief Minimum value of absolute values of a Q7 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] result is output pointer
* @param[in] index is the array index of the minimum value in the input buffer.
*/
void arm_absmin_q7(
const q7_t * pSrc,
uint32_t blockSize,
q7_t * result,
uint32_t * index);
/**
* @brief Minimum value of absolute values of a Q7 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] result is output pointer
*/
void arm_absmin_no_idx_q7(
const q7_t * pSrc,
uint32_t blockSize,
q7_t * result);
/**
* @brief Minimum value of a Q15 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output pointer
* @param[in] pIndex is the array index of the minimum value in the input buffer.
*/
void arm_min_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult,
uint32_t * pIndex);
/**
* @brief Minimum value of absolute values of a Q15 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output pointer
* @param[in] pIndex is the array index of the minimum value in the input buffer.
*/
void arm_absmin_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult,
uint32_t * pIndex);
/**
* @brief Minimum value of absolute values of a Q15 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output pointer
*/
void arm_absmin_no_idx_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult);
/**
* @brief Minimum value of a Q31 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output pointer
* @param[out] pIndex is the array index of the minimum value in the input buffer.
*/
void arm_min_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult,
uint32_t * pIndex);
/**
* @brief Minimum value of absolute values of a Q31 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output pointer
* @param[out] pIndex is the array index of the minimum value in the input buffer.
*/
void arm_absmin_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult,
uint32_t * pIndex);
/**
* @brief Minimum value of absolute values of a Q31 vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output pointer
*/
void arm_absmin_no_idx_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult);
/**
* @brief Minimum value of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output pointer
* @param[out] pIndex is the array index of the minimum value in the input buffer.
*/
void arm_min_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult,
uint32_t * pIndex);
/**
* @brief Minimum value of absolute values of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output pointer
* @param[out] pIndex is the array index of the minimum value in the input buffer.
*/
void arm_absmin_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult,
uint32_t * pIndex);
/**
* @brief Minimum value of absolute values of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output pointer
*/
void arm_absmin_no_idx_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult);
/**
* @brief Minimum value of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output pointer
* @param[out] pIndex is the array index of the minimum value in the input buffer.
*/
void arm_min_f64(
const float64_t * pSrc,
uint32_t blockSize,
float64_t * pResult,
uint32_t * pIndex);
/**
* @brief Minimum value of absolute values of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output pointer
* @param[out] pIndex is the array index of the minimum value in the input buffer.
*/
void arm_absmin_f64(
const float64_t * pSrc,
uint32_t blockSize,
float64_t * pResult,
uint32_t * pIndex);
/**
* @brief Minimum value of absolute values of a floating-point vector.
* @param[in] pSrc is input pointer
* @param[in] blockSize is the number of samples to process
* @param[out] pResult is output pointer
*/
void arm_absmin_no_idx_f64(
const float64_t * pSrc,
uint32_t blockSize,
float64_t * pResult);
/**
* @brief Maximum value of a Q7 vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
* @param[out] pIndex index of maximum value returned here
*/
void arm_max_q7(
const q7_t * pSrc,
uint32_t blockSize,
q7_t * pResult,
uint32_t * pIndex);
/**
* @brief Maximum value of absolute values of a Q7 vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
* @param[out] pIndex index of maximum value returned here
*/
void arm_absmax_q7(
const q7_t * pSrc,
uint32_t blockSize,
q7_t * pResult,
uint32_t * pIndex);
/**
* @brief Maximum value of absolute values of a Q7 vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
*/
void arm_absmax_no_idx_q7(
const q7_t * pSrc,
uint32_t blockSize,
q7_t * pResult);
/**
* @brief Maximum value of a Q15 vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
* @param[out] pIndex index of maximum value returned here
*/
void arm_max_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult,
uint32_t * pIndex);
/**
* @brief Maximum value of absolute values of a Q15 vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
* @param[out] pIndex index of maximum value returned here
*/
void arm_absmax_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult,
uint32_t * pIndex);
/**
* @brief Maximum value of absolute values of a Q15 vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
*/
void arm_absmax_no_idx_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult);
/**
* @brief Maximum value of a Q31 vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
* @param[out] pIndex index of maximum value returned here
*/
void arm_max_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult,
uint32_t * pIndex);
/**
* @brief Maximum value of absolute values of a Q31 vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
* @param[out] pIndex index of maximum value returned here
*/
void arm_absmax_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult,
uint32_t * pIndex);
/**
* @brief Maximum value of absolute values of a Q31 vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
*/
void arm_absmax_no_idx_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult);
/**
* @brief Maximum value of a floating-point vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
* @param[out] pIndex index of maximum value returned here
*/
void arm_max_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult,
uint32_t * pIndex);
/**
* @brief Maximum value of absolute values of a floating-point vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
* @param[out] pIndex index of maximum value returned here
*/
void arm_absmax_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult,
uint32_t * pIndex);
/**
* @brief Maximum value of absolute values of a floating-point vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
*/
void arm_absmax_no_idx_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult);
/**
* @brief Maximum value of a floating-point vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
* @param[out] pIndex index of maximum value returned here
*/
void arm_max_f64(
const float64_t * pSrc,
uint32_t blockSize,
float64_t * pResult,
uint32_t * pIndex);
/**
* @brief Maximum value of absolute values of a floating-point vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
* @param[out] pIndex index of maximum value returned here
*/
void arm_absmax_f64(
const float64_t * pSrc,
uint32_t blockSize,
float64_t * pResult,
uint32_t * pIndex);
/**
* @brief Maximum value of absolute values of a floating-point vector.
* @param[in] pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] pResult maximum value returned here
*/
void arm_absmax_no_idx_f64(
const float64_t * pSrc,
uint32_t blockSize,
float64_t * pResult);
/**
@brief Maximum value of a floating-point vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult maximum value returned here
@return none
*/
void arm_max_no_idx_f32(
const float32_t *pSrc,
uint32_t blockSize,
float32_t *pResult);
/**
@brief Minimum value of a floating-point vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult minimum value returned here
@return none
*/
void arm_min_no_idx_f32(
const float32_t *pSrc,
uint32_t blockSize,
float32_t *pResult);
/**
@brief Maximum value of a floating-point vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult maximum value returned here
@return none
*/
void arm_max_no_idx_f64(
const float64_t *pSrc,
uint32_t blockSize,
float64_t *pResult);
/**
@brief Maximum value of a q31 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult maximum value returned here
@return none
*/
void arm_max_no_idx_q31(
const q31_t *pSrc,
uint32_t blockSize,
q31_t *pResult);
/**
@brief Maximum value of a q15 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult maximum value returned here
@return none
*/
void arm_max_no_idx_q15(
const q15_t *pSrc,
uint32_t blockSize,
q15_t *pResult);
/**
@brief Maximum value of a q7 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult maximum value returned here
@return none
*/
void arm_max_no_idx_q7(
const q7_t *pSrc,
uint32_t blockSize,
q7_t *pResult);
/**
@brief Minimum value of a floating-point vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult minimum value returned here
@return none
*/
void arm_min_no_idx_f64(
const float64_t *pSrc,
uint32_t blockSize,
float64_t *pResult);
/**
@brief Minimum value of a q31 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult minimum value returned here
@return none
*/
void arm_min_no_idx_q31(
const q31_t *pSrc,
uint32_t blockSize,
q31_t *pResult);
/**
@brief Minimum value of a q15 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult minimum value returned here
@return none
*/
void arm_min_no_idx_q15(
const q15_t *pSrc,
uint32_t blockSize,
q15_t *pResult);
/**
@brief Minimum value of a q7 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult minimum value returned here
@return none
*/
void arm_min_no_idx_q7(
const q7_t *pSrc,
uint32_t blockSize,
q7_t *pResult);
/**
@brief Mean square error between two Q7 vectors.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult mean square error
@return none
*/
void arm_mse_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
uint32_t blockSize,
q7_t * pResult);
/**
@brief Mean square error between two Q15 vectors.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult mean square error
@return none
*/
void arm_mse_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
uint32_t blockSize,
q15_t * pResult);
/**
@brief Mean square error between two Q31 vectors.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult mean square error
@return none
*/
void arm_mse_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
uint32_t blockSize,
q31_t * pResult);
/**
@brief Mean square error between two single precision float vectors.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult mean square error
@return none
*/
void arm_mse_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
uint32_t blockSize,
float32_t * pResult);
/**
@brief Mean square error between two double precision float vectors.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult mean square error
@return none
*/
void arm_mse_f64(
const float64_t * pSrcA,
const float64_t * pSrcB,
uint32_t blockSize,
float64_t * pResult);
#ifdef __cplusplus
}
#endif
#endif /* ifndef _STATISTICS_FUNCTIONS_H_ */
@@ -0,0 +1,453 @@
/******************************************************************************
* @file support_functions.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _SUPPORT_FUNCTIONS_H_
#define _SUPPORT_FUNCTIONS_H_
#include "arm_math_types.h"
#include "arm_math_memory.h"
#include "dsp/none.h"
#include "dsp/utils.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @defgroup groupSupport Support Functions
*/
/**
* @brief Converts the elements of the floating-point vector to Q31 vector.
* @param[in] pSrc points to the floating-point input vector
* @param[out] pDst points to the Q31 output vector
* @param[in] blockSize length of the input vector
*/
void arm_float_to_q31(
const float32_t * pSrc,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the floating-point vector to Q15 vector.
* @param[in] pSrc points to the floating-point input vector
* @param[out] pDst points to the Q15 output vector
* @param[in] blockSize length of the input vector
*/
void arm_float_to_q15(
const float32_t * pSrc,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the floating-point vector to Q7 vector.
* @param[in] pSrc points to the floating-point input vector
* @param[out] pDst points to the Q7 output vector
* @param[in] blockSize length of the input vector
*/
void arm_float_to_q7(
const float32_t * pSrc,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q31 vector to floating-point vector.
* @param[in] pSrc is input pointer
* @param[out] pDst is output pointer
* @param[in] blockSize is the number of samples to process
*/
void arm_q31_to_float(
const q31_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q31 vector to Q15 vector.
* @param[in] pSrc is input pointer
* @param[out] pDst is output pointer
* @param[in] blockSize is the number of samples to process
*/
void arm_q31_to_q15(
const q31_t * pSrc,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q31 vector to Q7 vector.
* @param[in] pSrc is input pointer
* @param[out] pDst is output pointer
* @param[in] blockSize is the number of samples to process
*/
void arm_q31_to_q7(
const q31_t * pSrc,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q15 vector to floating-point vector.
* @param[in] pSrc is input pointer
* @param[out] pDst is output pointer
* @param[in] blockSize is the number of samples to process
*/
void arm_q15_to_float(
const q15_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q15 vector to Q31 vector.
* @param[in] pSrc is input pointer
* @param[out] pDst is output pointer
* @param[in] blockSize is the number of samples to process
*/
void arm_q15_to_q31(
const q15_t * pSrc,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q15 vector to Q7 vector.
* @param[in] pSrc is input pointer
* @param[out] pDst is output pointer
* @param[in] blockSize is the number of samples to process
*/
void arm_q15_to_q7(
const q15_t * pSrc,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q7 vector to floating-point vector.
* @param[in] pSrc is input pointer
* @param[out] pDst is output pointer
* @param[in] blockSize is the number of samples to process
*/
void arm_q7_to_float(
const q7_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q7 vector to Q31 vector.
* @param[in] pSrc input pointer
* @param[out] pDst output pointer
* @param[in] blockSize number of samples to process
*/
void arm_q7_to_q31(
const q7_t * pSrc,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q7 vector to Q15 vector.
* @param[in] pSrc input pointer
* @param[out] pDst output pointer
* @param[in] blockSize number of samples to process
*/
void arm_q7_to_q15(
const q7_t * pSrc,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Struct for specifying sorting algorithm
*/
typedef enum
{
ARM_SORT_BITONIC = 0,
/**< Bitonic sort */
ARM_SORT_BUBBLE = 1,
/**< Bubble sort */
ARM_SORT_HEAP = 2,
/**< Heap sort */
ARM_SORT_INSERTION = 3,
/**< Insertion sort */
ARM_SORT_QUICK = 4,
/**< Quick sort */
ARM_SORT_SELECTION = 5
/**< Selection sort */
} arm_sort_alg;
/**
* @brief Struct for specifying sorting algorithm
*/
typedef enum
{
ARM_SORT_DESCENDING = 0,
/**< Descending order (9 to 0) */
ARM_SORT_ASCENDING = 1
/**< Ascending order (0 to 9) */
} arm_sort_dir;
/**
* @brief Instance structure for the sorting algorithms.
*/
typedef struct
{
arm_sort_alg alg; /**< Sorting algorithm selected */
arm_sort_dir dir; /**< Sorting order (direction) */
} arm_sort_instance_f32;
/**
* @param[in] S points to an instance of the sorting structure.
* @param[in] pSrc points to the block of input data.
* @param[out] pDst points to the block of output data.
* @param[in] blockSize number of samples to process.
*/
void arm_sort_f32(
const arm_sort_instance_f32 * S,
float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
* @param[in,out] S points to an instance of the sorting structure.
* @param[in] alg Selected algorithm.
* @param[in] dir Sorting order.
*/
void arm_sort_init_f32(
arm_sort_instance_f32 * S,
arm_sort_alg alg,
arm_sort_dir dir);
/**
* @brief Instance structure for the sorting algorithms.
*/
typedef struct
{
arm_sort_dir dir; /**< Sorting order (direction) */
float32_t * buffer; /**< Working buffer */
} arm_merge_sort_instance_f32;
/**
* @param[in] S points to an instance of the sorting structure.
* @param[in,out] pSrc points to the block of input data.
* @param[out] pDst points to the block of output data
* @param[in] blockSize number of samples to process.
*/
void arm_merge_sort_f32(
const arm_merge_sort_instance_f32 * S,
float32_t *pSrc,
float32_t *pDst,
uint32_t blockSize);
/**
* @param[in,out] S points to an instance of the sorting structure.
* @param[in] dir Sorting order.
* @param[in] buffer Working buffer.
*/
void arm_merge_sort_init_f32(
arm_merge_sort_instance_f32 * S,
arm_sort_dir dir,
float32_t * buffer);
/**
* @brief Copies the elements of a floating-point vector.
* @param[in] pSrc input pointer
* @param[out] pDst output pointer
* @param[in] blockSize number of samples to process
*/
void arm_copy_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Copies the elements of a floating-point vector.
* @param[in] pSrc input pointer
* @param[out] pDst output pointer
* @param[in] blockSize number of samples to process
*/
void arm_copy_f64(
const float64_t * pSrc,
float64_t * pDst,
uint32_t blockSize);
/**
* @brief Copies the elements of a Q7 vector.
* @param[in] pSrc input pointer
* @param[out] pDst output pointer
* @param[in] blockSize number of samples to process
*/
void arm_copy_q7(
const q7_t * pSrc,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Copies the elements of a Q15 vector.
* @param[in] pSrc input pointer
* @param[out] pDst output pointer
* @param[in] blockSize number of samples to process
*/
void arm_copy_q15(
const q15_t * pSrc,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Copies the elements of a Q31 vector.
* @param[in] pSrc input pointer
* @param[out] pDst output pointer
* @param[in] blockSize number of samples to process
*/
void arm_copy_q31(
const q31_t * pSrc,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Fills a constant value into a floating-point vector.
* @param[in] value input value to be filled
* @param[out] pDst output pointer
* @param[in] blockSize number of samples to process
*/
void arm_fill_f32(
float32_t value,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Fills a constant value into a floating-point vector.
* @param[in] value input value to be filled
* @param[out] pDst output pointer
* @param[in] blockSize number of samples to process
*/
void arm_fill_f64(
float64_t value,
float64_t * pDst,
uint32_t blockSize);
/**
* @brief Fills a constant value into a Q7 vector.
* @param[in] value input value to be filled
* @param[out] pDst output pointer
* @param[in] blockSize number of samples to process
*/
void arm_fill_q7(
q7_t value,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Fills a constant value into a Q15 vector.
* @param[in] value input value to be filled
* @param[out] pDst output pointer
* @param[in] blockSize number of samples to process
*/
void arm_fill_q15(
q15_t value,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Fills a constant value into a Q31 vector.
* @param[in] value input value to be filled
* @param[out] pDst output pointer
* @param[in] blockSize number of samples to process
*/
void arm_fill_q31(
q31_t value,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Weighted sum
*
*
* @param[in] *in Array of input values.
* @param[in] *weigths Weights
* @param[in] blockSize Number of samples in the input array.
* @return Weighted sum
*
*/
float32_t arm_weighted_sum_f32(const float32_t *in
, const float32_t *weigths
, uint32_t blockSize);
/**
* @brief Barycenter
*
*
* @param[in] in List of vectors
* @param[in] weights Weights of the vectors
* @param[out] out Barycenter
* @param[in] nbVectors Number of vectors
* @param[in] vecDim Dimension of space (vector dimension)
* @return None
*
*/
void arm_barycenter_f32(const float32_t *in
, const float32_t *weights
, float32_t *out
, uint32_t nbVectors
, uint32_t vecDim);
#ifdef __cplusplus
}
#endif
#endif /* ifndef _SUPPORT_FUNCTIONS_H_ */
@@ -0,0 +1,735 @@
/******************************************************************************
* @file transform_functions.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _TRANSFORM_FUNCTIONS_H_
#define _TRANSFORM_FUNCTIONS_H_
#include "arm_math_types.h"
#include "arm_math_memory.h"
#include "dsp/none.h"
#include "dsp/utils.h"
#include "dsp/basic_math_functions.h"
#include "dsp/complex_math_functions.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @defgroup groupTransforms Transform Functions
*/
/**
* @brief Instance structure for the Q15 CFFT/CIFFT function.
*/
typedef struct
{
uint16_t fftLen; /**< length of the FFT. */
uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
const q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */
const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
} arm_cfft_radix2_instance_q15;
/* Deprecated */
arm_status arm_cfft_radix2_init_q15(
arm_cfft_radix2_instance_q15 * S,
uint16_t fftLen,
uint8_t ifftFlag,
uint8_t bitReverseFlag);
/* Deprecated */
void arm_cfft_radix2_q15(
const arm_cfft_radix2_instance_q15 * S,
q15_t * pSrc);
/**
* @brief Instance structure for the Q15 CFFT/CIFFT function.
*/
typedef struct
{
uint16_t fftLen; /**< length of the FFT. */
uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
const q15_t *pTwiddle; /**< points to the twiddle factor table. */
const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
} arm_cfft_radix4_instance_q15;
/* Deprecated */
arm_status arm_cfft_radix4_init_q15(
arm_cfft_radix4_instance_q15 * S,
uint16_t fftLen,
uint8_t ifftFlag,
uint8_t bitReverseFlag);
/* Deprecated */
void arm_cfft_radix4_q15(
const arm_cfft_radix4_instance_q15 * S,
q15_t * pSrc);
/**
* @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function.
*/
typedef struct
{
uint16_t fftLen; /**< length of the FFT. */
uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
const q31_t *pTwiddle; /**< points to the Twiddle factor table. */
const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
} arm_cfft_radix2_instance_q31;
/* Deprecated */
arm_status arm_cfft_radix2_init_q31(
arm_cfft_radix2_instance_q31 * S,
uint16_t fftLen,
uint8_t ifftFlag,
uint8_t bitReverseFlag);
/* Deprecated */
void arm_cfft_radix2_q31(
const arm_cfft_radix2_instance_q31 * S,
q31_t * pSrc);
/**
* @brief Instance structure for the Q31 CFFT/CIFFT function.
*/
typedef struct
{
uint16_t fftLen; /**< length of the FFT. */
uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
const q31_t *pTwiddle; /**< points to the twiddle factor table. */
const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
} arm_cfft_radix4_instance_q31;
/* Deprecated */
void arm_cfft_radix4_q31(
const arm_cfft_radix4_instance_q31 * S,
q31_t * pSrc);
/* Deprecated */
arm_status arm_cfft_radix4_init_q31(
arm_cfft_radix4_instance_q31 * S,
uint16_t fftLen,
uint8_t ifftFlag,
uint8_t bitReverseFlag);
/**
* @brief Instance structure for the floating-point CFFT/CIFFT function.
*/
typedef struct
{
uint16_t fftLen; /**< length of the FFT. */
uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
const float32_t *pTwiddle; /**< points to the Twiddle factor table. */
const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
float32_t onebyfftLen; /**< value of 1/fftLen. */
} arm_cfft_radix2_instance_f32;
/* Deprecated */
arm_status arm_cfft_radix2_init_f32(
arm_cfft_radix2_instance_f32 * S,
uint16_t fftLen,
uint8_t ifftFlag,
uint8_t bitReverseFlag);
/* Deprecated */
void arm_cfft_radix2_f32(
const arm_cfft_radix2_instance_f32 * S,
float32_t * pSrc);
/**
* @brief Instance structure for the floating-point CFFT/CIFFT function.
*/
typedef struct
{
uint16_t fftLen; /**< length of the FFT. */
uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
const float32_t *pTwiddle; /**< points to the Twiddle factor table. */
const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
float32_t onebyfftLen; /**< value of 1/fftLen. */
} arm_cfft_radix4_instance_f32;
/* Deprecated */
arm_status arm_cfft_radix4_init_f32(
arm_cfft_radix4_instance_f32 * S,
uint16_t fftLen,
uint8_t ifftFlag,
uint8_t bitReverseFlag);
/* Deprecated */
void arm_cfft_radix4_f32(
const arm_cfft_radix4_instance_f32 * S,
float32_t * pSrc);
/**
* @brief Instance structure for the fixed-point CFFT/CIFFT function.
*/
typedef struct
{
uint16_t fftLen; /**< length of the FFT. */
const q15_t *pTwiddle; /**< points to the Twiddle factor table. */
const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
uint16_t bitRevLength; /**< bit reversal table length. */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
const uint32_t *rearranged_twiddle_tab_stride1_arr; /**< Per stage reordered twiddle pointer (offset 1) */ \
const uint32_t *rearranged_twiddle_tab_stride2_arr; /**< Per stage reordered twiddle pointer (offset 2) */ \
const uint32_t *rearranged_twiddle_tab_stride3_arr; /**< Per stage reordered twiddle pointer (offset 3) */ \
const q15_t *rearranged_twiddle_stride1; /**< reordered twiddle offset 1 storage */ \
const q15_t *rearranged_twiddle_stride2; /**< reordered twiddle offset 2 storage */ \
const q15_t *rearranged_twiddle_stride3;
#endif
} arm_cfft_instance_q15;
arm_status arm_cfft_init_q15(
arm_cfft_instance_q15 * S,
uint16_t fftLen);
void arm_cfft_q15(
const arm_cfft_instance_q15 * S,
q15_t * p1,
uint8_t ifftFlag,
uint8_t bitReverseFlag);
/**
* @brief Instance structure for the fixed-point CFFT/CIFFT function.
*/
typedef struct
{
uint16_t fftLen; /**< length of the FFT. */
const q31_t *pTwiddle; /**< points to the Twiddle factor table. */
const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
uint16_t bitRevLength; /**< bit reversal table length. */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
const uint32_t *rearranged_twiddle_tab_stride1_arr; /**< Per stage reordered twiddle pointer (offset 1) */ \
const uint32_t *rearranged_twiddle_tab_stride2_arr; /**< Per stage reordered twiddle pointer (offset 2) */ \
const uint32_t *rearranged_twiddle_tab_stride3_arr; /**< Per stage reordered twiddle pointer (offset 3) */ \
const q31_t *rearranged_twiddle_stride1; /**< reordered twiddle offset 1 storage */ \
const q31_t *rearranged_twiddle_stride2; /**< reordered twiddle offset 2 storage */ \
const q31_t *rearranged_twiddle_stride3;
#endif
} arm_cfft_instance_q31;
arm_status arm_cfft_init_q31(
arm_cfft_instance_q31 * S,
uint16_t fftLen);
void arm_cfft_q31(
const arm_cfft_instance_q31 * S,
q31_t * p1,
uint8_t ifftFlag,
uint8_t bitReverseFlag);
/**
* @brief Instance structure for the floating-point CFFT/CIFFT function.
*/
typedef struct
{
uint16_t fftLen; /**< length of the FFT. */
const float32_t *pTwiddle; /**< points to the Twiddle factor table. */
const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
uint16_t bitRevLength; /**< bit reversal table length. */
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
const uint32_t *rearranged_twiddle_tab_stride1_arr; /**< Per stage reordered twiddle pointer (offset 1) */ \
const uint32_t *rearranged_twiddle_tab_stride2_arr; /**< Per stage reordered twiddle pointer (offset 2) */ \
const uint32_t *rearranged_twiddle_tab_stride3_arr; /**< Per stage reordered twiddle pointer (offset 3) */ \
const float32_t *rearranged_twiddle_stride1; /**< reordered twiddle offset 1 storage */ \
const float32_t *rearranged_twiddle_stride2; /**< reordered twiddle offset 2 storage */ \
const float32_t *rearranged_twiddle_stride3;
#endif
} arm_cfft_instance_f32;
arm_status arm_cfft_init_f32(
arm_cfft_instance_f32 * S,
uint16_t fftLen);
void arm_cfft_f32(
const arm_cfft_instance_f32 * S,
float32_t * p1,
uint8_t ifftFlag,
uint8_t bitReverseFlag);
/**
* @brief Instance structure for the Double Precision Floating-point CFFT/CIFFT function.
*/
typedef struct
{
uint16_t fftLen; /**< length of the FFT. */
const float64_t *pTwiddle; /**< points to the Twiddle factor table. */
const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
uint16_t bitRevLength; /**< bit reversal table length. */
} arm_cfft_instance_f64;
arm_status arm_cfft_init_f64(
arm_cfft_instance_f64 * S,
uint16_t fftLen);
void arm_cfft_f64(
const arm_cfft_instance_f64 * S,
float64_t * p1,
uint8_t ifftFlag,
uint8_t bitReverseFlag);
/**
* @brief Instance structure for the Q15 RFFT/RIFFT function.
*/
typedef struct
{
uint32_t fftLenReal; /**< length of the real FFT. */
uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
const q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
const q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
arm_cfft_instance_q15 cfftInst;
#else
const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */
#endif
} arm_rfft_instance_q15;
arm_status arm_rfft_init_q15(
arm_rfft_instance_q15 * S,
uint32_t fftLenReal,
uint32_t ifftFlagR,
uint32_t bitReverseFlag);
void arm_rfft_q15(
const arm_rfft_instance_q15 * S,
q15_t * pSrc,
q15_t * pDst);
/**
* @brief Instance structure for the Q31 RFFT/RIFFT function.
*/
typedef struct
{
uint32_t fftLenReal; /**< length of the real FFT. */
uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
const q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
const q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
arm_cfft_instance_q31 cfftInst;
#else
const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */
#endif
} arm_rfft_instance_q31;
arm_status arm_rfft_init_q31(
arm_rfft_instance_q31 * S,
uint32_t fftLenReal,
uint32_t ifftFlagR,
uint32_t bitReverseFlag);
void arm_rfft_q31(
const arm_rfft_instance_q31 * S,
q31_t * pSrc,
q31_t * pDst);
/**
* @brief Instance structure for the floating-point RFFT/RIFFT function.
*/
typedef struct
{
uint32_t fftLenReal; /**< length of the real FFT. */
uint16_t fftLenBy2; /**< length of the complex FFT. */
uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
const float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
const float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
} arm_rfft_instance_f32;
arm_status arm_rfft_init_f32(
arm_rfft_instance_f32 * S,
arm_cfft_radix4_instance_f32 * S_CFFT,
uint32_t fftLenReal,
uint32_t ifftFlagR,
uint32_t bitReverseFlag);
void arm_rfft_f32(
const arm_rfft_instance_f32 * S,
float32_t * pSrc,
float32_t * pDst);
/**
* @brief Instance structure for the Double Precision Floating-point RFFT/RIFFT function.
*/
typedef struct
{
arm_cfft_instance_f64 Sint; /**< Internal CFFT structure. */
uint16_t fftLenRFFT; /**< length of the real sequence */
const float64_t * pTwiddleRFFT; /**< Twiddle factors real stage */
} arm_rfft_fast_instance_f64 ;
arm_status arm_rfft_fast_init_f64 (
arm_rfft_fast_instance_f64 * S,
uint16_t fftLen);
void arm_rfft_fast_f64(
arm_rfft_fast_instance_f64 * S,
float64_t * p, float64_t * pOut,
uint8_t ifftFlag);
/**
* @brief Instance structure for the floating-point RFFT/RIFFT function.
*/
typedef struct
{
arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */
uint16_t fftLenRFFT; /**< length of the real sequence */
const float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */
} arm_rfft_fast_instance_f32 ;
arm_status arm_rfft_fast_init_f32 (
arm_rfft_fast_instance_f32 * S,
uint16_t fftLen);
void arm_rfft_fast_f32(
const arm_rfft_fast_instance_f32 * S,
float32_t * p, float32_t * pOut,
uint8_t ifftFlag);
/**
* @brief Instance structure for the floating-point DCT4/IDCT4 function.
*/
typedef struct
{
uint16_t N; /**< length of the DCT4. */
uint16_t Nby2; /**< half of the length of the DCT4. */
float32_t normalize; /**< normalizing factor. */
const float32_t *pTwiddle; /**< points to the twiddle factor table. */
const float32_t *pCosFactor; /**< points to the cosFactor table. */
arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */
arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
} arm_dct4_instance_f32;
/**
* @brief Initialization function for the floating-point DCT4/IDCT4.
* @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure.
* @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure.
* @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure.
* @param[in] N length of the DCT4.
* @param[in] Nby2 half of the length of the DCT4.
* @param[in] normalize normalizing factor.
* @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLenReal</code> is not a supported transform length.
*/
arm_status arm_dct4_init_f32(
arm_dct4_instance_f32 * S,
arm_rfft_instance_f32 * S_RFFT,
arm_cfft_radix4_instance_f32 * S_CFFT,
uint16_t N,
uint16_t Nby2,
float32_t normalize);
/**
* @brief Processing function for the floating-point DCT4/IDCT4.
* @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure.
* @param[in] pState points to state buffer.
* @param[in,out] pInlineBuffer points to the in-place input and output buffer.
*/
void arm_dct4_f32(
const arm_dct4_instance_f32 * S,
float32_t * pState,
float32_t * pInlineBuffer);
/**
* @brief Instance structure for the Q31 DCT4/IDCT4 function.
*/
typedef struct
{
uint16_t N; /**< length of the DCT4. */
uint16_t Nby2; /**< half of the length of the DCT4. */
q31_t normalize; /**< normalizing factor. */
const q31_t *pTwiddle; /**< points to the twiddle factor table. */
const q31_t *pCosFactor; /**< points to the cosFactor table. */
arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */
arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */
} arm_dct4_instance_q31;
/**
* @brief Initialization function for the Q31 DCT4/IDCT4.
* @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure.
* @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure
* @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure
* @param[in] N length of the DCT4.
* @param[in] Nby2 half of the length of the DCT4.
* @param[in] normalize normalizing factor.
* @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>N</code> is not a supported transform length.
*/
arm_status arm_dct4_init_q31(
arm_dct4_instance_q31 * S,
arm_rfft_instance_q31 * S_RFFT,
arm_cfft_radix4_instance_q31 * S_CFFT,
uint16_t N,
uint16_t Nby2,
q31_t normalize);
/**
* @brief Processing function for the Q31 DCT4/IDCT4.
* @param[in] S points to an instance of the Q31 DCT4 structure.
* @param[in] pState points to state buffer.
* @param[in,out] pInlineBuffer points to the in-place input and output buffer.
*/
void arm_dct4_q31(
const arm_dct4_instance_q31 * S,
q31_t * pState,
q31_t * pInlineBuffer);
/**
* @brief Instance structure for the Q15 DCT4/IDCT4 function.
*/
typedef struct
{
uint16_t N; /**< length of the DCT4. */
uint16_t Nby2; /**< half of the length of the DCT4. */
q15_t normalize; /**< normalizing factor. */
const q15_t *pTwiddle; /**< points to the twiddle factor table. */
const q15_t *pCosFactor; /**< points to the cosFactor table. */
arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */
arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */
} arm_dct4_instance_q15;
/**
* @brief Initialization function for the Q15 DCT4/IDCT4.
* @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure.
* @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure.
* @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure.
* @param[in] N length of the DCT4.
* @param[in] Nby2 half of the length of the DCT4.
* @param[in] normalize normalizing factor.
* @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>N</code> is not a supported transform length.
*/
arm_status arm_dct4_init_q15(
arm_dct4_instance_q15 * S,
arm_rfft_instance_q15 * S_RFFT,
arm_cfft_radix4_instance_q15 * S_CFFT,
uint16_t N,
uint16_t Nby2,
q15_t normalize);
/**
* @brief Processing function for the Q15 DCT4/IDCT4.
* @param[in] S points to an instance of the Q15 DCT4 structure.
* @param[in] pState points to state buffer.
* @param[in,out] pInlineBuffer points to the in-place input and output buffer.
*/
void arm_dct4_q15(
const arm_dct4_instance_q15 * S,
q15_t * pState,
q15_t * pInlineBuffer);
/**
* @brief Instance structure for the Floating-point MFCC function.
*/
typedef struct
{
const float32_t *dctCoefs; /**< Internal DCT coefficients */
const float32_t *filterCoefs; /**< Internal Mel filter coefficients */
const float32_t *windowCoefs; /**< Windowing coefficients */
const uint32_t *filterPos; /**< Internal Mel filter positions in spectrum */
const uint32_t *filterLengths; /**< Internal Mel filter lengths */
uint32_t fftLen; /**< FFT length */
uint32_t nbMelFilters; /**< Number of Mel filters */
uint32_t nbDctOutputs; /**< Number of DCT outputs */
#if defined(ARM_MFCC_CFFT_BASED)
/* Implementation of the MFCC is using a CFFT */
arm_cfft_instance_f32 cfft; /**< Internal CFFT instance */
#else
/* Implementation of the MFCC is using a RFFT (default) */
arm_rfft_fast_instance_f32 rfft;
#endif
} arm_mfcc_instance_f32 ;
arm_status arm_mfcc_init_f32(
arm_mfcc_instance_f32 * S,
uint32_t fftLen,
uint32_t nbMelFilters,
uint32_t nbDctOutputs,
const float32_t *dctCoefs,
const uint32_t *filterPos,
const uint32_t *filterLengths,
const float32_t *filterCoefs,
const float32_t *windowCoefs
);
/**
@brief MFCC F32
@param[in] S points to the mfcc instance structure
@param[in] pSrc points to the input samples
@param[out] pDst points to the output MFCC values
@param[inout] pTmp points to a temporary buffer of complex
@return none
*/
void arm_mfcc_f32(
const arm_mfcc_instance_f32 * S,
float32_t *pSrc,
float32_t *pDst,
float32_t *pTmp
);
typedef struct
{
const q31_t *dctCoefs; /**< Internal DCT coefficients */
const q31_t *filterCoefs; /**< Internal Mel filter coefficients */
const q31_t *windowCoefs; /**< Windowing coefficients */
const uint32_t *filterPos; /**< Internal Mel filter positions in spectrum */
const uint32_t *filterLengths; /**< Internal Mel filter lengths */
uint32_t fftLen; /**< FFT length */
uint32_t nbMelFilters; /**< Number of Mel filters */
uint32_t nbDctOutputs; /**< Number of DCT outputs */
#if defined(ARM_MFCC_CFFT_BASED)
/* Implementation of the MFCC is using a CFFT */
arm_cfft_instance_q31 cfft; /**< Internal CFFT instance */
#else
/* Implementation of the MFCC is using a RFFT (default) */
arm_rfft_instance_q31 rfft;
#endif
} arm_mfcc_instance_q31 ;
arm_status arm_mfcc_init_q31(
arm_mfcc_instance_q31 * S,
uint32_t fftLen,
uint32_t nbMelFilters,
uint32_t nbDctOutputs,
const q31_t *dctCoefs,
const uint32_t *filterPos,
const uint32_t *filterLengths,
const q31_t *filterCoefs,
const q31_t *windowCoefs
);
/**
@brief MFCC Q31
@param[in] S points to the mfcc instance structure
@param[in] pSrc points to the input samples
@param[out] pDst points to the output MFCC values
@param[inout] pTmp points to a temporary buffer of complex
@return none
*/
arm_status arm_mfcc_q31(
const arm_mfcc_instance_q31 * S,
q31_t *pSrc,
q31_t *pDst,
q31_t *pTmp
);
typedef struct
{
const q15_t *dctCoefs; /**< Internal DCT coefficients */
const q15_t *filterCoefs; /**< Internal Mel filter coefficients */
const q15_t *windowCoefs; /**< Windowing coefficients */
const uint32_t *filterPos; /**< Internal Mel filter positions in spectrum */
const uint32_t *filterLengths; /**< Internal Mel filter lengths */
uint32_t fftLen; /**< FFT length */
uint32_t nbMelFilters; /**< Number of Mel filters */
uint32_t nbDctOutputs; /**< Number of DCT outputs */
#if defined(ARM_MFCC_CFFT_BASED)
/* Implementation of the MFCC is using a CFFT */
arm_cfft_instance_q15 cfft; /**< Internal CFFT instance */
#else
/* Implementation of the MFCC is using a RFFT (default) */
arm_rfft_instance_q15 rfft;
#endif
} arm_mfcc_instance_q15 ;
arm_status arm_mfcc_init_q15(
arm_mfcc_instance_q15 * S,
uint32_t fftLen,
uint32_t nbMelFilters,
uint32_t nbDctOutputs,
const q15_t *dctCoefs,
const uint32_t *filterPos,
const uint32_t *filterLengths,
const q15_t *filterCoefs,
const q15_t *windowCoefs
);
/**
@brief MFCC Q15
@param[in] S points to the mfcc instance structure
@param[in] pSrc points to the input samples
@param[out] pDst points to the output MFCC values in q8.7 format
@param[inout] pTmp points to a temporary buffer of complex
@return error status
*/
arm_status arm_mfcc_q15(
const arm_mfcc_instance_q15 * S,
q15_t *pSrc,
q15_t *pDst,
q31_t *pTmp
);
#ifdef __cplusplus
}
#endif
#endif /* ifndef _TRANSFORM_FUNCTIONS_H_ */
@@ -0,0 +1,240 @@
/******************************************************************************
* @file arm_math_utils.h
* @brief Public header file for CMSIS DSP Library
* @version V1.9.0
* @date 20. July 2020
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARM_MATH_UTILS_H_
#define _ARM_MATH_UTILS_H_
#include "arm_math_types.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Macros required for reciprocal calculation in Normalized LMS
*/
#define INDEX_MASK 0x0000003F
#define SQ(x) ((x) * (x))
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
/**
* @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type.
*/
__STATIC_FORCEINLINE uint32_t arm_recip_q31(
q31_t in,
q31_t * dst,
const q31_t * pRecipTable)
{
q31_t out;
uint32_t tempVal;
uint32_t index, i;
uint32_t signBits;
if (in > 0)
{
signBits = ((uint32_t) (__CLZ( in) - 1));
}
else
{
signBits = ((uint32_t) (__CLZ(-in) - 1));
}
/* Convert input sample to 1.31 format */
in = (in << signBits);
/* calculation of index for initial approximated Val */
index = (uint32_t)(in >> 24);
index = (index & INDEX_MASK);
/* 1.31 with exp 1 */
out = pRecipTable[index];
/* calculation of reciprocal value */
/* running approximation for two iterations */
for (i = 0U; i < 2U; i++)
{
tempVal = (uint32_t) (((q63_t) in * out) >> 31);
tempVal = 0x7FFFFFFFu - tempVal;
/* 1.31 with exp 1 */
/* out = (q31_t) (((q63_t) out * tempVal) >> 30); */
out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30);
}
/* write output */
*dst = out;
/* return num of signbits of out = 1/in value */
return (signBits + 1U);
}
/**
* @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type.
*/
__STATIC_FORCEINLINE uint32_t arm_recip_q15(
q15_t in,
q15_t * dst,
const q15_t * pRecipTable)
{
q15_t out = 0;
uint32_t tempVal = 0;
uint32_t index = 0, i = 0;
uint32_t signBits = 0;
if (in > 0)
{
signBits = ((uint32_t)(__CLZ( in) - 17));
}
else
{
signBits = ((uint32_t)(__CLZ(-in) - 17));
}
/* Convert input sample to 1.15 format */
in = (in << signBits);
/* calculation of index for initial approximated Val */
index = (uint32_t)(in >> 8);
index = (index & INDEX_MASK);
/* 1.15 with exp 1 */
out = pRecipTable[index];
/* calculation of reciprocal value */
/* running approximation for two iterations */
for (i = 0U; i < 2U; i++)
{
tempVal = (uint32_t) (((q31_t) in * out) >> 15);
tempVal = 0x7FFFu - tempVal;
/* 1.15 with exp 1 */
out = (q15_t) (((q31_t) out * tempVal) >> 14);
/* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */
}
/* write output */
*dst = out;
/* return num of signbits of out = 1/in value */
return (signBits + 1);
}
/**
* @brief 64-bit to 32-bit unsigned normalization
* @param[in] in is input unsigned long long value
* @param[out] normalized is the 32-bit normalized value
* @param[out] norm is norm scale
*/
__STATIC_INLINE void arm_norm_64_to_32u(uint64_t in, int32_t * normalized, int32_t *norm)
{
int32_t n1;
int32_t hi = (int32_t) (in >> 32);
int32_t lo = (int32_t) ((in << 32) >> 32);
n1 = __CLZ(hi) - 32;
if (!n1)
{
/*
* input fits in 32-bit
*/
n1 = __CLZ(lo);
if (!n1)
{
/*
* MSB set, need to scale down by 1
*/
*norm = -1;
*normalized = (((uint32_t) lo) >> 1);
} else
{
if (n1 == 32)
{
/*
* input is zero
*/
*norm = 0;
*normalized = 0;
} else
{
/*
* 32-bit normalization
*/
*norm = n1 - 1;
*normalized = lo << *norm;
}
}
} else
{
/*
* input fits in 64-bit
*/
n1 = 1 - n1;
*norm = -n1;
/*
* 64 bit normalization
*/
*normalized = (((uint32_t) lo) >> n1) | (hi << (32 - n1));
}
}
__STATIC_INLINE q31_t arm_div_q63_to_q31(q63_t num, q31_t den)
{
q31_t result;
uint64_t absNum;
int32_t normalized;
int32_t norm;
/*
* if sum fits in 32bits
* avoid costly 64-bit division
*/
absNum = num > 0 ? num : -num;
arm_norm_64_to_32u(absNum, &normalized, &norm);
if (norm > 0)
/*
* 32-bit division
*/
result = (q31_t) num / den;
else
/*
* 64-bit division
*/
result = (q31_t) (num / den);
return result;
}
#ifdef __cplusplus
}
#endif
#endif /*ifndef _ARM_MATH_UTILS_H_ */
@@ -0,0 +1,200 @@
/******************************************************************************
* @file arm_sorting.h
* @brief Private header file for CMSIS DSP Library
* @version V1.7.0
* @date 2019
******************************************************************************/
/*
* Copyright (c) 2010-2019 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARM_SORTING_H_
#define _ARM_SORTING_H_
#include "arm_math.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @param[in] S points to an instance of the sorting structure.
* @param[in] pSrc points to the block of input data.
* @param[out] pDst points to the block of output data.
* @param[in] blockSize number of samples to process.
*/
void arm_bubble_sort_f32(
const arm_sort_instance_f32 * S,
float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
* @param[in] S points to an instance of the sorting structure.
* @param[in] pSrc points to the block of input data.
* @param[out] pDst points to the block of output data.
* @param[in] blockSize number of samples to process.
*/
void arm_heap_sort_f32(
const arm_sort_instance_f32 * S,
float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
* @param[in] S points to an instance of the sorting structure.
* @param[in] pSrc points to the block of input data.
* @param[out] pDst points to the block of output data.
* @param[in] blockSize number of samples to process.
*/
void arm_insertion_sort_f32(
const arm_sort_instance_f32 * S,
float32_t *pSrc,
float32_t* pDst,
uint32_t blockSize);
/**
* @param[in] S points to an instance of the sorting structure.
* @param[in] pSrc points to the block of input data.
* @param[out] pDst points to the block of output data
* @param[in] blockSize number of samples to process.
*/
void arm_quick_sort_f32(
const arm_sort_instance_f32 * S,
float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
* @param[in] S points to an instance of the sorting structure.
* @param[in] pSrc points to the block of input data.
* @param[out] pDst points to the block of output data
* @param[in] blockSize number of samples to process.
*/
void arm_selection_sort_f32(
const arm_sort_instance_f32 * S,
float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
* @param[in] S points to an instance of the sorting structure.
* @param[in] pSrc points to the block of input data.
* @param[out] pDst points to the block of output data
* @param[in] blockSize number of samples to process.
*/
void arm_bitonic_sort_f32(
const arm_sort_instance_f32 * S,
float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
#if defined(ARM_MATH_NEON)
#define vtrn256_128q(a, b) \
do { \
float32x4_t vtrn128_temp = a.val[1]; \
a.val[1] = b.val[0]; \
b.val[0] = vtrn128_temp ; \
} while (0)
#define vtrn128_64q(a, b) \
do { \
float32x2_t ab, cd, ef, gh; \
ab = vget_low_f32(a); \
ef = vget_low_f32(b); \
cd = vget_high_f32(a); \
gh = vget_high_f32(b); \
a = vcombine_f32(ab, ef); \
b = vcombine_f32(cd, gh); \
} while (0)
#define vtrn256_64q(a, b) \
do { \
float32x2_t a_0, a_1, a_2, a_3; \
float32x2_t b_0, b_1, b_2, b_3; \
a_0 = vget_low_f32(a.val[0]); \
a_1 = vget_high_f32(a.val[0]); \
a_2 = vget_low_f32(a.val[1]); \
a_3 = vget_high_f32(a.val[1]); \
b_0 = vget_low_f32(b.val[0]); \
b_1 = vget_high_f32(b.val[0]); \
b_2 = vget_low_f32(b.val[1]); \
b_3 = vget_high_f32(b.val[1]); \
a.val[0] = vcombine_f32(a_0, b_0); \
a.val[1] = vcombine_f32(a_2, b_2); \
b.val[0] = vcombine_f32(a_1, b_1); \
b.val[1] = vcombine_f32(a_3, b_3); \
} while (0)
#define vtrn128_32q(a, b) \
do { \
float32x4x2_t vtrn32_tmp = vtrnq_f32((a), (b)); \
(a) = vtrn32_tmp.val[0]; \
(b) = vtrn32_tmp.val[1]; \
} while (0)
#define vtrn256_32q(a, b) \
do { \
float32x4x2_t vtrn32_tmp_1 = vtrnq_f32((a.val[0]), (b.val[0])); \
float32x4x2_t vtrn32_tmp_2 = vtrnq_f32((a.val[1]), (b.val[1])); \
a.val[0] = vtrn32_tmp_1.val[0]; \
a.val[1] = vtrn32_tmp_2.val[0]; \
b.val[0] = vtrn32_tmp_1.val[1]; \
b.val[1] = vtrn32_tmp_2.val[1]; \
} while (0)
#define vminmaxq(a, b) \
do { \
float32x4_t minmax_tmp = (a); \
(a) = vminq_f32((a), (b)); \
(b) = vmaxq_f32(minmax_tmp, (b)); \
} while (0)
#define vminmax256q(a, b) \
do { \
float32x4x2_t minmax256_tmp = (a); \
a.val[0] = vminq_f32(a.val[0], b.val[0]); \
a.val[1] = vminq_f32(a.val[1], b.val[1]); \
b.val[0] = vmaxq_f32(minmax256_tmp.val[0], b.val[0]); \
b.val[1] = vmaxq_f32(minmax256_tmp.val[1], b.val[1]); \
} while (0)
#define vrev128q_f32(a) \
vcombine_f32(vrev64_f32(vget_high_f32(a)), vrev64_f32(vget_low_f32(a)))
#define vrev256q_f32(a) \
do { \
float32x4_t rev_tmp = vcombine_f32(vrev64_f32(vget_high_f32(a.val[0])), vrev64_f32(vget_low_f32(a.val[0]))); \
a.val[0] = vcombine_f32(vrev64_f32(vget_high_f32(a.val[1])), vrev64_f32(vget_low_f32(a.val[1]))); \
a.val[1] = rev_tmp; \
} while (0)
#define vldrev128q_f32(a, p) \
do { \
a = vld1q_f32(p); \
a = vrev128q_f32(a); \
} while (0)
#endif /* ARM_MATH_NEON */
#ifdef __cplusplus
}
#endif
#endif /* _ARM_SORTING_H */
@@ -0,0 +1,325 @@
/******************************************************************************
* @file arm_vec_fft.h
* @brief Private header file for CMSIS DSP Library
* @version V1.7.0
* @date 07. January 2020
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARM_VEC_FFT_H_
#define _ARM_VEC_FFT_H_
#include "arm_math.h"
#include "arm_helium_utils.h"
#ifdef __cplusplus
extern "C"
{
#endif
#if (defined(ARM_MATH_MVEF) || defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE)
#define MVE_CMPLX_ADD_A_ixB(A, B) vcaddq_rot90(A,B)
#define MVE_CMPLX_SUB_A_ixB(A,B) vcaddq_rot270(A,B)
#define MVE_CMPLX_MULT_FLT_AxB(A,B) vcmlaq_rot90(vcmulq(A, B), A, B)
#define MVE_CMPLX_MULT_FLT_Conj_AxB(A,B) vcmlaq_rot270(vcmulq(A, B), A, B)
#define MVE_CMPLX_MULT_FX_AxB(A,B,TyA) vqdmladhxq(vqdmlsdhq((TyA)vuninitializedq_s32(), A, B), A, B)
#define MVE_CMPLX_MULT_FX_AxConjB(A,B,TyA) vqdmladhq(vqdmlsdhxq((TyA)vuninitializedq_s32(), A, B), A, B)
#define MVE_CMPLX_ADD_FX_A_ixB(A, B) vhcaddq_rot90(A,B)
#define MVE_CMPLX_SUB_FX_A_ixB(A,B) vhcaddq_rot270(A,B)
/**
@brief In-place 32 bit reversal function for helium
@param[in,out] pSrc points to in-place buffer of unknown 32-bit data type
@param[in] bitRevLen bit reversal table length
@param[in] pBitRevTab points to bit reversal table
@return none
*/
__STATIC_INLINE void arm_bitreversal_32_inpl_mve(
uint32_t *pSrc,
const uint16_t bitRevLen,
const uint16_t *pBitRevTab)
{
uint64_t *src = (uint64_t *) pSrc;
int32_t blkCnt; /* loop counters */
uint32x4_t bitRevTabOff;
uint32x4_t one = vdupq_n_u32(1);
uint64x2_t inLow, inHigh;
uint64x2_t bitRevOff1Low, bitRevOff0Low;
uint64x2_t bitRevOff1High, bitRevOff0High;
/* load scheduling to increase gather load idx update / gather load distance */
bitRevTabOff = vldrhq_u32(pBitRevTab);
pBitRevTab += 4;
bitRevOff0Low = vmullbq_int_u32(bitRevTabOff, one);
bitRevOff0High = vmulltq_int_u32(bitRevTabOff, one);
blkCnt = bitRevLen / 8;
while (blkCnt > 0) {
bitRevTabOff = vldrhq_u32(pBitRevTab);
pBitRevTab += 4;
/* 64-bit index expansion */
bitRevOff1Low = vmullbq_int_u32(bitRevTabOff, one);
bitRevOff1High = vmulltq_int_u32(bitRevTabOff, one);
inLow = vldrdq_gather_offset_u64(src, bitRevOff0Low);
inHigh = vldrdq_gather_offset_u64(src, bitRevOff0High);
vstrdq_scatter_offset_u64(src, bitRevOff0Low, inHigh);
vstrdq_scatter_offset_u64(src, bitRevOff0High, inLow);
/* unrolled */
bitRevTabOff = vldrhq_u32(pBitRevTab);
pBitRevTab += 4;
bitRevOff0Low = vmullbq_int_u32(bitRevTabOff, one);
bitRevOff0High = vmulltq_int_u32(bitRevTabOff, one);
inLow = vldrdq_gather_offset_u64(src, bitRevOff1Low);
inHigh = vldrdq_gather_offset_u64(src, bitRevOff1High);
vstrdq_scatter_offset_u64(src, bitRevOff1Low, inHigh);
vstrdq_scatter_offset_u64(src, bitRevOff1High, inLow);
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
}
if (bitRevLen & 7) {
/* FFT size = 16 */
inLow = vldrdq_gather_offset_u64(src, bitRevOff0Low);
inHigh = vldrdq_gather_offset_u64(src, bitRevOff0High);
vstrdq_scatter_offset_u64(src, bitRevOff0Low, inHigh);
vstrdq_scatter_offset_u64(src, bitRevOff0High, inLow);
}
}
/**
@brief In-place 16 bit reversal function for helium
@param[in,out] pSrc points to in-place buffer of unknown 16-bit data type
@param[in] bitRevLen bit reversal table length
@param[in] pBitRevTab points to bit reversal table
@return none
*/
__STATIC_INLINE void arm_bitreversal_16_inpl_mve(
uint16_t *pSrc,
const uint16_t bitRevLen,
const uint16_t *pBitRevTab)
{
uint32_t *src = (uint32_t *) pSrc;
int32_t blkCnt; /* loop counters */
uint32x4_t bitRevTabOff;
uint16x8_t one = vdupq_n_u16(1);
uint32x4_t bitRevOff1Low, bitRevOff0Low;
uint32x4_t bitRevOff1High, bitRevOff0High;
uint32x4_t inLow, inHigh;
/* load scheduling to increase gather load idx update / gather load distance */
bitRevTabOff = vldrhq_u16(pBitRevTab);
pBitRevTab += 8;
bitRevOff0Low = vmullbq_int_u16((uint16x8_t)bitRevTabOff, one);
bitRevOff0High = vmulltq_int_u16((uint16x8_t)bitRevTabOff, one);
bitRevOff0Low = vshrq_n_u16((uint16x8_t)bitRevOff0Low, 3);
bitRevOff0High = vshrq_n_u16((uint16x8_t)bitRevOff0High, 3);
blkCnt = (bitRevLen / 16);
while (blkCnt > 0) {
bitRevTabOff = vldrhq_u16(pBitRevTab);
pBitRevTab += 8;
bitRevOff1Low = vmullbq_int_u16((uint16x8_t)bitRevTabOff, one);
bitRevOff1High = vmulltq_int_u16((uint16x8_t)bitRevTabOff, one);
bitRevOff1Low = vshrq_n_u16((uint16x8_t)bitRevOff1Low, 3);
bitRevOff1High = vshrq_n_u16((uint16x8_t)bitRevOff1High, 3);
inLow = vldrwq_gather_shifted_offset_u32(src, bitRevOff0Low);
inHigh = vldrwq_gather_shifted_offset_u32(src, bitRevOff0High);
vstrwq_scatter_shifted_offset_u32(src, bitRevOff0Low, inHigh);
vstrwq_scatter_shifted_offset_u32(src, bitRevOff0High, inLow);
/* loop unrolling */
bitRevTabOff = vldrhq_u16(pBitRevTab);
pBitRevTab += 8;
bitRevOff0Low = vmullbq_int_u16((uint16x8_t)bitRevTabOff, one);
bitRevOff0High = vmulltq_int_u16((uint16x8_t)bitRevTabOff, one);
bitRevOff0Low = vshrq_n_u16((uint16x8_t)bitRevOff0Low, 3);
bitRevOff0High = vshrq_n_u16((uint16x8_t)bitRevOff0High, 3);
inLow = vldrwq_gather_shifted_offset_u32(src, bitRevOff1Low);
inHigh = vldrwq_gather_shifted_offset_u32(src, bitRevOff1High);
vstrwq_scatter_shifted_offset_u32(src, bitRevOff1Low, inHigh);
vstrwq_scatter_shifted_offset_u32(src, bitRevOff1High, inLow);
blkCnt--;
}
/* tail handling */
blkCnt = bitRevLen & 0xf;
if (blkCnt == 8) {
inLow = vldrwq_gather_shifted_offset_u32(src, bitRevOff0Low);
inHigh = vldrwq_gather_shifted_offset_u32(src, bitRevOff0High);
vstrwq_scatter_shifted_offset_u32(src, bitRevOff0Low, inHigh);
vstrwq_scatter_shifted_offset_u32(src, bitRevOff0High, inLow);
} else if (blkCnt == 12) {
/* FFT 16 special case */
mve_pred16_t p = vctp16q(4);
bitRevTabOff = vldrhq_z_u16(pBitRevTab, p);
inLow = vldrwq_gather_shifted_offset_u32(src, bitRevOff0Low);
inHigh = vldrwq_gather_shifted_offset_u32(src, bitRevOff0High);
vstrwq_scatter_shifted_offset_u32(src, bitRevOff0Low, inHigh);
vstrwq_scatter_shifted_offset_u32(src, bitRevOff0High, inLow);
bitRevOff0Low = vmullbq_int_u16((uint16x8_t)bitRevTabOff, one);
bitRevOff0High = vmulltq_int_u16((uint16x8_t)bitRevTabOff, one);
bitRevOff0Low = vshrq_n_u16((uint16x8_t)bitRevOff0Low, 3);
bitRevOff0High = vshrq_n_u16((uint16x8_t)bitRevOff0High, 3);
inLow = vldrwq_gather_shifted_offset_z_u32(src, bitRevOff0Low, p);
inHigh = vldrwq_gather_shifted_offset_z_u32(src, bitRevOff0High, p);
vstrwq_scatter_shifted_offset_p_u32(src, bitRevOff0Low, inHigh, p);
vstrwq_scatter_shifted_offset_p_u32(src, bitRevOff0High, inLow, p);
}
}
/**
@brief Out-of-place 32 bit reversal function for helium
@param[out] pDst points to destination buffer of unknown 32-bit data type
@param[in] pSrc points to input buffer of unknown 32-bit data type
@param[in] fftLen FFT length
@return none
*/
__STATIC_INLINE void arm_bitreversal_32_outpl_mve(void *pDst, void *pSrc, uint32_t fftLen)
{
uint32x4_t idxOffs0, idxOffs1, bitRevOffs0, bitRevOffs1;
uint32_t bitRevPos, blkCnt;
uint32_t *pDst32 = (uint32_t *) pDst;
/* fwd indexes */
idxOffs0 = vdupq_n_u32(0);
idxOffs1 = vdupq_n_u32(0);
idxOffs0[0] = 0; idxOffs0[2] = 4;
idxOffs1[0] = 8; idxOffs1[2] = 12;
bitRevPos = (31 - __CLZ(fftLen)) + 5;
blkCnt = fftLen >> 2;
/* issued earlier to increase gather load idx update / gather load distance */
/* bit-reverse fwd indexes */
bitRevOffs0 = vbrsrq(idxOffs0, bitRevPos);
bitRevOffs1 = vbrsrq(idxOffs1, bitRevPos);
while (blkCnt > 0) {
uint64x2_t vecIn;
vecIn = vldrdq_gather_offset_u64(pSrc, (uint64x2_t) bitRevOffs0);
idxOffs0 = idxOffs0 + 16;
vst1q(pDst32, (uint32x4_t) vecIn);
pDst32 += 4;
bitRevOffs0 = vbrsrq(idxOffs0, bitRevPos);
vecIn = vldrdq_gather_offset_u64(pSrc, (uint64x2_t) bitRevOffs1);
idxOffs1 = idxOffs1 + 16;
vst1q(pDst32, (uint32x4_t) vecIn);
pDst32 += 4;
bitRevOffs1 = vbrsrq(idxOffs1, bitRevPos);
blkCnt--;
}
}
/**
@brief Out-of-place 16 bit reversal function for helium
@param[out] pDst points to destination buffer of unknown 16-bit data type
@param[in] pSrc points to input buffer of unknown 16-bit data type
@param[in] fftLen FFT length
@return none
*/
__STATIC_INLINE void arm_bitreversal_16_outpl_mve(void *pDst, void *pSrc, uint32_t fftLen)
{
uint32x4_t idxOffs0, idxOffs1, bitRevOffs0, bitRevOffs1;
uint32_t bitRevPos, blkCnt;
uint16_t *pDst16 = (uint16_t *) pDst;
uint32_t incrIdx = 0;
/* fwd indexes */
idxOffs0 = vidupq_wb_u32(&incrIdx, 4); // {0, 4, 8, 12}
idxOffs1 = vidupq_wb_u32(&incrIdx, 4); // {16, 20, 24, 28}
bitRevPos = (31 - __CLZ(fftLen)) + 4;
blkCnt = fftLen >> 3;
/* issued earlier to increase gather load idx update / gather load distance */
/* bit-reverse fwd indexes */
bitRevOffs0 = vbrsrq(idxOffs0, bitRevPos);
bitRevOffs1 = vbrsrq(idxOffs1, bitRevPos);
while (blkCnt > 0) {
uint32x4_t vecIn;
vecIn = vldrwq_gather_offset_s32(pSrc, bitRevOffs0);
idxOffs0 = idxOffs0 + 32;
vst1q(pDst16, (uint16x8_t) vecIn);
pDst16 += 8;
bitRevOffs0 = vbrsrq(idxOffs0, bitRevPos);
vecIn = vldrwq_gather_offset_s32(pSrc, bitRevOffs1);
idxOffs1 = idxOffs1 + 32;
vst1q(pDst16, (uint16x8_t) vecIn);
pDst16 += 8;
bitRevOffs1 = vbrsrq(idxOffs1, bitRevPos);
blkCnt--;
}
}
#endif /* (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE)*/
#ifdef __cplusplus
}
#endif
#endif /* _ARM_VEC_FFT_H_ */
@@ -0,0 +1,196 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_abs_f32.c
* Description: Floating-point vector absolute value
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
#include <math.h>
/**
@ingroup groupMath
*/
/**
@defgroup BasicAbs Vector Absolute Value
Computes the absolute value of a vector on an element-by-element basis.
<pre>
pDst[n] = abs(pSrc[n]), 0 <= n < blockSize.
</pre>
The functions support in-place computation allowing the source and
destination pointers to reference the same memory buffer.
There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
@addtogroup BasicAbs
@{
*/
/**
@brief Floating-point vector absolute value.
@param[in] pSrc points to the input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_abs_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
f32x4_t vec1;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute values and then store the results in the destination buffer. */
vec1 = vld1q(pSrc);
res = vabsq(vec1);
vst1q(pDst, res);
/* Increment pointers */
pSrc += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
if (blkCnt > 0U)
{
/* C = |A| */
mve_pred16_t p0 = vctp32q(blkCnt);
vec1 = vld1q(pSrc);
vstrwq_p(pDst, vabsq(vec1), p0);
}
}
#else
void arm_abs_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
f32x4_t vec1;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute values and then store the results in the destination buffer. */
vec1 = vld1q_f32(pSrc);
res = vabsq_f32(vec1);
vst1q_f32(pDst, res);
/* Increment pointers */
pSrc += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
#else
#if defined (ARM_MATH_LOOPUNROLL) && !defined(ARM_MATH_AUTOVECTORIZE)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute and store result in destination buffer. */
*pDst++ = fabsf(*pSrc++);
*pDst++ = fabsf(*pSrc++);
*pDst++ = fabsf(*pSrc++);
*pDst++ = fabsf(*pSrc++);
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
#endif /* #if defined(ARM_MATH_NEON) */
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute and store result in destination buffer. */
*pDst++ = fabsf(*pSrc++);
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
/**
@} end of BasicAbs group
*/
@@ -0,0 +1,74 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_abs_f64.c
* Description: Floating-point vector absolute value
*
* $Date: 13 September 2021
* $Revision: V1.10.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
#include <math.h>
/**
@ingroup groupMath
*/
/**
@addtogroup BasicAbs
@{
*/
/**
@brief Floating-point vector absolute value.
@param[in] pSrc points to the input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_abs_f64(
const float64_t * pSrc,
float64_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute and store result in destination buffer. */
*pDst++ = fabs(*pSrc++);
/* Decrement loop counter */
blkCnt--;
}
}
/**
@} end of BasicAbs group
*/
@@ -0,0 +1,178 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_abs_q15.c
* Description: Q15 vector absolute value
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicAbs
@{
*/
/**
@brief Q15 vector absolute value.
@param[in] pSrc points to the input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
The Q15 value -1 (0x8000) will be saturated to the maximum allowable positive value 0x7FFF.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_abs_q15(
const q15_t * pSrc,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q15x8_t vecSrc;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
/*
* C = |A|
* Calculate absolute and then store the results in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vst1q(pDst, vqabsq(vecSrc));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 8;
pDst += 8;
}
/*
* tail
*/
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecSrc = vld1q(pSrc);
vstrhq_p(pDst, vqabsq(vecSrc), p0);
}
}
#else
void arm_abs_q15(
const q15_t * pSrc,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
q15_t in; /* Temporary input variable */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute of input (if -1 then saturated to 0x7fff) and store result in destination buffer. */
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in);
#endif
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in);
#endif
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in);
#endif
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute of input (if -1 then saturated to 0x7fff) and store result in destination buffer. */
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in);
#endif
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicAbs group
*/
@@ -0,0 +1,208 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_abs_q31.c
* Description: Q31 vector absolute value
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicAbs
@{
*/
/**
@brief Q31 vector absolute value.
@param[in] pSrc points to the input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
The Q31 value -1 (0x80000000) will be saturated to the maximum allowable positive value 0x7FFFFFFF.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_abs_q31(
const q31_t * pSrc,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counters */
q31x4_t vecSrc;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
/*
* C = |A|
* Calculate absolute and then store the results in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vst1q(pDst, vqabsq(vecSrc));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* Advance vector source and destination pointers
*/
pSrc += 4;
pDst += 4;
}
/*
* Tail
*/
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecSrc = vld1q(pSrc);
vstrwq_p(pDst, vqabsq(vecSrc), p0);
}
}
#else
void arm_abs_q31(
const q31_t * pSrc,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
q31_t in; /* Temporary variable */
#if defined(ARM_MATH_NEON)
int32x4_t vec1;
int32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute and then store the results in the destination buffer. */
vec1 = vld1q_s32(pSrc);
res = vqabsq_s32(vec1);
vst1q_s32(pDst, res);
/* Increment pointers */
pSrc += 4;
pDst += 4;
/* Decrement the blockSize loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
#else
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute of input (if -1 then saturated to 0x7fffffff) and store result in destination buffer. */
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in);
#endif
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in);
#endif
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in);
#endif
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
#endif /* #if defined (ARM_MATH_NEON) */
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute of input (if -1 then saturated to 0x7fffffff) and store result in destination buffer. */
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in);
#endif
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* #if defined (ARM_MATH_MVEI) */
/**
@} end of BasicAbs group
*/
@@ -0,0 +1,180 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_abs_q7.c
* Description: Q7 vector absolute value
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicAbs
@{
*/
/**
@brief Q7 vector absolute value.
@param[in] pSrc points to the input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Conditions for optimum performance
Input and output buffers should be aligned by 32-bit
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
The Q7 value -1 (0x80) will be saturated to the maximum allowable positive value 0x7F.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_abs_q7(
const q7_t * pSrc,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q7x16_t vecSrc;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4;
while (blkCnt > 0U)
{
/*
* C = |A|
* Calculate absolute and then store the results in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vst1q(pDst, vqabsq(vecSrc));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 16;
pDst += 16;
}
/*
* tail
*/
blkCnt = blockSize & 0xF;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp8q(blkCnt);
vecSrc = vld1q(pSrc);
vstrbq_p(pDst, vqabsq(vecSrc), p0);
}
}
#else
void arm_abs_q7(
const q7_t * pSrc,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
q7_t in; /* Temporary input variable */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute of input (if -1 then saturated to 0x7f) and store result in destination buffer. */
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q7_t)__QSUB8(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in);
#endif
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q7_t)__QSUB8(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in);
#endif
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q7_t)__QSUB8(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in);
#endif
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q7_t)__QSUB8(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute of input (if -1 then saturated to 0x7f) and store result in destination buffer. */
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (in > 0) ? in : (q7_t) __QSUB8(0, in);
#else
*pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in);
#endif
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicAbs group
*/
@@ -0,0 +1,199 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_add_f32.c
* Description: Floating-point vector addition
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup BasicAdd Vector Addition
Element-by-element addition of two vectors.
<pre>
pDst[n] = pSrcA[n] + pSrcB[n], 0 <= n < blockSize.
</pre>
There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
@addtogroup BasicAdd
@{
*/
/**
@brief Floating-point vector addition.
@param[in] pSrcA points to first input vector
@param[in] pSrcB points to second input vector
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_add_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
f32x4_t vec1;
f32x4_t vec2;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + B */
/* Add and then store the results in the destination buffer. */
vec1 = vld1q(pSrcA);
vec2 = vld1q(pSrcB);
res = vaddq(vec1, vec2);
vst1q(pDst, res);
/* Increment pointers */
pSrcA += 4;
pSrcB += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
if (blkCnt > 0U)
{
/* C = A + B */
mve_pred16_t p0 = vctp32q(blkCnt);
vec1 = vld1q(pSrcA);
vec2 = vld1q(pSrcB);
vstrwq_p(pDst, vaddq(vec1,vec2), p0);
}
}
#else
void arm_add_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
f32x4_t vec1;
f32x4_t vec2;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + B */
/* Add and then store the results in the destination buffer. */
vec1 = vld1q_f32(pSrcA);
vec2 = vld1q_f32(pSrcB);
res = vaddq_f32(vec1, vec2);
vst1q_f32(pDst, res);
/* Increment pointers */
pSrcA += 4;
pSrcB += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
#else
#if defined (ARM_MATH_LOOPUNROLL) && !defined(ARM_MATH_AUTOVECTORIZE)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + B */
/* Add and store result in destination buffer. */
*pDst++ = (*pSrcA++) + (*pSrcB++);
*pDst++ = (*pSrcA++) + (*pSrcB++);
*pDst++ = (*pSrcA++) + (*pSrcB++);
*pDst++ = (*pSrcA++) + (*pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
#endif /* #if defined(ARM_MATH_NEON) */
while (blkCnt > 0U)
{
/* C = A + B */
/* Add and store result in destination buffer. */
*pDst++ = (*pSrcA++) + (*pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
/**
@} end of BasicAdd group
*/
@@ -0,0 +1,75 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_add_f64.c
* Description: Floating-point vector addition
*
* $Date: 13 September 2021
* $Revision: V1.10.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicAdd
@{
*/
/**
@brief Floating-point vector addition.
@param[in] pSrcA points to first input vector
@param[in] pSrcB points to second input vector
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_add_f64(
const float64_t * pSrcA,
const float64_t * pSrcB,
float64_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
while (blkCnt > 0U)
{
/* C = A + B */
/* Add and store result in destination buffer. */
*pDst++ = (*pSrcA++) + (*pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
}
/**
@} end of BasicAdd group
*/
@@ -0,0 +1,176 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_add_q15.c
* Description: Q15 vector addition
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicAdd
@{
*/
/**
@brief Q15 vector addition.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_add_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q15x8_t vecA;
q15x8_t vecB;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
/*
* C = A + B
* Add and then store the results in the destination buffer.
*/
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vst1q(pDst, vqaddq(vecA, vecB));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrcA += 8;
pSrcB += 8;
pDst += 8;
}
/*
* tail
*/
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vstrhq_p(pDst, vqaddq(vecA, vecB), p0);
}
}
#else
void arm_add_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q31_t inA1, inA2;
q31_t inB1, inB2;
#endif
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + B */
#if defined (ARM_MATH_DSP)
/* read 2 times 2 samples at a time from sourceA */
inA1 = read_q15x2_ia (&pSrcA);
inA2 = read_q15x2_ia (&pSrcA);
/* read 2 times 2 samples at a time from sourceB */
inB1 = read_q15x2_ia (&pSrcB);
inB2 = read_q15x2_ia (&pSrcB);
/* Add and store 2 times 2 samples at a time */
write_q15x2_ia (&pDst, __QADD16(inA1, inB1));
write_q15x2_ia (&pDst, __QADD16(inA2, inB2));
#else
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16);
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16);
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16);
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A + B */
/* Add and store result in destination buffer. */
#if defined (ARM_MATH_DSP)
*pDst++ = (q15_t) __QADD16(*pSrcA++, *pSrcB++);
#else
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16);
#endif
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicAdd group
*/
@@ -0,0 +1,159 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_add_q31.c
* Description: Q31 vector addition
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicAdd
@{
*/
/**
@brief Q31 vector addition.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_add_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt;
q31x4_t vecA;
q31x4_t vecB;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
/*
* C = A + B
* Add and then store the results in the destination buffer.
*/
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vst1q(pDst, vqaddq(vecA, vecB));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrcA += 4;
pSrcB += 4;
pDst += 4;
}
/*
* tail
*/
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vstrwq_p(pDst, vqaddq(vecA, vecB), p0);
}
}
#else
void arm_add_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + B */
/* Add and store result in destination buffer. */
*pDst++ = __QADD(*pSrcA++, *pSrcB++);
*pDst++ = __QADD(*pSrcA++, *pSrcB++);
*pDst++ = __QADD(*pSrcA++, *pSrcB++);
*pDst++ = __QADD(*pSrcA++, *pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A + B */
/* Add and store result in destination buffer. */
*pDst++ = __QADD(*pSrcA++, *pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicAdd group
*/
@@ -0,0 +1,159 @@
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_add_q7.c
* Description: Q7 vector addition
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicAdd
@{
*/
/**
@brief Q7 vector addition.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q7 range [0x80 0x7F] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_add_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q7x16_t vecA;
q7x16_t vecB;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4;
while (blkCnt > 0U)
{
/*
* C = A + B
* Add and then store the results in the destination buffer.
*/
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vst1q(pDst, vqaddq(vecA, vecB));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrcA += 16;
pSrcB += 16;
pDst += 16;
}
/*
* tail
*/
blkCnt = blockSize & 0xF;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp8q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vstrbq_p(pDst, vqaddq(vecA, vecB), p0);
}
}
#else
void arm_add_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + B */
#if defined (ARM_MATH_DSP)
/* Add and store result in destination buffer (4 samples at a time). */
write_q7x4_ia (&pDst, __QADD8 (read_q7x4_ia (&pSrcA), read_q7x4_ia (&pSrcB)));
#else
*pDst++ = (q7_t) __SSAT ((q15_t) *pSrcA++ + *pSrcB++, 8);
*pDst++ = (q7_t) __SSAT ((q15_t) *pSrcA++ + *pSrcB++, 8);
*pDst++ = (q7_t) __SSAT ((q15_t) *pSrcA++ + *pSrcB++, 8);
*pDst++ = (q7_t) __SSAT ((q15_t) *pSrcA++ + *pSrcB++, 8);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A + B */
/* Add and store result in destination buffer. */
*pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ + *pSrcB++, 8);
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicAdd group
*/
@@ -0,0 +1,153 @@
/*****************************************************************************/
/**
* Description: A brief description of this file
*
* Author: Fan Hao
* Date: 2022-10-13 15:21
* LastEditors: Fan Hao
* LastEditTime: 2022-10-13 16:15
* Revisions: Rev x.x
* History:
* [YYYY-MM-DD]: Description of modification.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_and_u16.c
* Description: uint16_t bitwise AND
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup And Vector bitwise AND
Compute the logical bitwise AND.
There are separate functions for uint32_t, uint16_t, and uint7_t data types.
*/
/**
@addtogroup And
@{
*/
/**
@brief Compute the logical bitwise AND of two fixed-point vectors.
@param[in] pSrcA points to input vector A
@param[in] pSrcB points to input vector B
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_and_u16(
const uint16_t * pSrcA,
const uint16_t * pSrcB,
uint16_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
uint16x8_t vecSrcA, vecSrcB;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vst1q(pDst, vandq_u16(vecSrcA, vecSrcB) );
pSrcA += 8;
pSrcB += 8;
pDst += 8;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vstrhq_p(pDst, vandq_u16(vecSrcA, vecSrcB), p0);
}
#else
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
uint16x8_t vecA, vecB;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3U;
while (blkCnt > 0U)
{
vecA = vld1q_u16(pSrcA);
vecB = vld1q_u16(pSrcB);
vst1q_u16(pDst, vandq_u16(vecA, vecB) );
pSrcA += 8;
pSrcB += 8;
pDst += 8;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 7;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif
while (blkCnt > 0U)
{
*pDst++ = (*pSrcA++)&(*pSrcB++);
/* Decrement the loop counter */
blkCnt--;
}
#endif /* if defined(ARM_MATH_MVEI) */
}
/**
@} end of And group
*/
@@ -0,0 +1,129 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_and_u32.c
* Description: uint32_t bitwise AND
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup And
@{
*/
/**
@brief Compute the logical bitwise AND of two fixed-point vectors.
@param[in] pSrcA points to input vector A
@param[in] pSrcB points to input vector B
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_and_u32(
const uint32_t * pSrcA,
const uint32_t * pSrcB,
uint32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
uint32x4_t vecSrcA, vecSrcB;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vst1q(pDst, vandq_u32(vecSrcA, vecSrcB) );
pSrcA += 4;
pSrcB += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vstrwq_p(pDst, vandq_u32(vecSrcA, vecSrcB), p0);
}
#else
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
uint32x4_t vecA, vecB;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
vecA = vld1q_u32(pSrcA);
vecB = vld1q_u32(pSrcB);
vst1q_u32(pDst, vandq_u32(vecA, vecB) );
pSrcA += 4;
pSrcB += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 3;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif
while (blkCnt > 0U)
{
*pDst++ = (*pSrcA++)&(*pSrcB++);
/* Decrement the loop counter */
blkCnt--;
}
#endif /* if defined(ARM_MATH_MVEI) */
}
/**
@} end of And group
*/
@@ -0,0 +1,130 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_and_u8.c
* Description: uint8_t bitwise AND
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup And
@{
*/
/**
@brief Compute the logical bitwise AND of two fixed-point vectors.
@param[in] pSrcA points to input vector A
@param[in] pSrcB points to input vector B
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_and_u8(
const uint8_t * pSrcA,
const uint8_t * pSrcB,
uint8_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
uint8x16_t vecSrcA, vecSrcB;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4;
while (blkCnt > 0U)
{
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vst1q(pDst, vandq_u8(vecSrcA, vecSrcB) );
pSrcA += 16;
pSrcB += 16;
pDst += 16;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0xF;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp8q(blkCnt);
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vstrbq_p(pDst, vandq_u8(vecSrcA, vecSrcB), p0);
}
#else
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
uint8x16_t vecA, vecB;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4U;
while (blkCnt > 0U)
{
vecA = vld1q_u8(pSrcA);
vecB = vld1q_u8(pSrcB);
vst1q_u8(pDst, vandq_u8(vecA, vecB) );
pSrcA += 16;
pSrcB += 16;
pDst += 16;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0xF;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif
while (blkCnt > 0U)
{
*pDst++ = (*pSrcA++)&(*pSrcB++);
/* Decrement the loop counter */
blkCnt--;
}
#endif /* if defined(ARM_MATH_MVEI) */
}
/**
@} end of And group
*/
@@ -0,0 +1,144 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_clip_f32.c
* Description: Floating-point vector addition
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup BasicClip Elementwise clipping
Element-by-element clipping of a value.
The value is constrained between 2 bounds.
There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
@addtogroup BasicClip
@{
*/
/**
@brief Elementwise floating-point clipping
@param[in] pSrc points to input values
@param[out] pDst points to output clipped values
@param[in] low lower bound
@param[in] high higher bound
@param[in] numSamples number of samples to clip
@return none
*/
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_clip_f32(const float32_t * pSrc,
float32_t * pDst,
float32_t low,
float32_t high,
uint32_t numSamples)
{
uint32_t blkCnt;
f32x4_t curVec0, curVec1;
f32x4_t vecLow, vecHigh;
vecLow = vdupq_n_f32(low);
vecHigh = vdupq_n_f32(high);
curVec0 = vld1q(pSrc);
pSrc += 4;
/*
* unrolled x 2 to allow
* vldr/vstr/vmin/vmax
* stall free interleaving
*/
blkCnt = numSamples >> 3;
while (blkCnt--)
{
curVec0 = vmaxnmq(curVec0, vecLow);
curVec1 = vld1q(pSrc);
pSrc += 4;
curVec0 = vminnmq(curVec0, vecHigh);
vst1q(pDst, curVec0);
pDst += 4;
curVec1 = vmaxnmq(curVec1, vecLow);
curVec0 = vld1q(pSrc);
pSrc += 4;
curVec1 = vminnmq(curVec1, vecHigh);
vst1q(pDst, curVec1);
pDst += 4;
}
/*
* Tail handling
*/
blkCnt = numSamples - ((numSamples >> 3) << 3);
if (blkCnt >= 4)
{
curVec0 = vmaxnmq(curVec0, vecLow);
curVec0 = vminnmq(curVec0, vecHigh);
vst1q(pDst, curVec0);
pDst += 4;
curVec0 = vld1q(pSrc);
pSrc += 4;
}
if (blkCnt > 0)
{
mve_pred16_t p0 = vctp32q(blkCnt & 3);
curVec0 = vmaxnmq(curVec0, vecLow);
curVec0 = vminnmq(curVec0, vecHigh);
vstrwq_p(pDst, curVec0, p0);
}
}
#else
void arm_clip_f32(const float32_t * pSrc,
float32_t * pDst,
float32_t low,
float32_t high,
uint32_t numSamples)
{
uint32_t i;
for (i = 0; i < numSamples; i++)
{
if (pSrc[i] > high)
pDst[i] = high;
else if (pSrc[i] < low)
pDst[i] = low;
else
pDst[i] = pSrc[i];
}
}
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
/**
@} end of BasicClip group
*/
@@ -0,0 +1,134 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_clip_q15.c
* Description: Floating-point vector addition
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicClip
@{
*/
/**
@brief Elementwise fixed-point clipping
@param[in] pSrc points to input values
@param[out] pDst points to output clipped values
@param[in] low lower bound
@param[in] high higher bound
@param[in] numSamples number of samples to clip
@return none
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_clip_q15(const q15_t * pSrc,
q15_t * pDst,
q15_t low,
q15_t high,
uint32_t numSamples)
{
uint32_t blkCnt;
q15x8_t curVec0, curVec1;
q15x8_t vecLow, vecHigh;
vecLow = vdupq_n_s16(low);
vecHigh = vdupq_n_s16(high);
curVec0 = vld1q(pSrc);
pSrc += 8;
/*
* unrolled x 2 to allow
* vldr/vstr/vmin/vmax
* stall free interleaving
*/
blkCnt = numSamples >> 4;
while (blkCnt--)
{
curVec0 = vmaxq(curVec0, vecLow);
curVec1 = vld1q(pSrc);
pSrc += 8;
curVec0 = vminq(curVec0, vecHigh);
vst1q(pDst, curVec0);
pDst += 8;
curVec1 = vmaxq(curVec1, vecLow);
curVec0 = vld1q(pSrc);
pSrc += 8;
curVec1 = vminq(curVec1, vecHigh);
vst1q(pDst, curVec1);
pDst += 8;
}
/*
* Tail handling
*/
blkCnt = numSamples - ((numSamples >> 4) << 4);
if (blkCnt >= 8)
{
curVec0 = vmaxq(curVec0, vecLow);
curVec0 = vminq(curVec0, vecHigh);
vst1q(pDst, curVec0);
pDst += 8;
curVec0 = vld1q(pSrc);
pSrc += 8;
}
if (blkCnt > 0)
{
mve_pred16_t p0 = vctp16q(blkCnt & 7);
curVec0 = vmaxq(curVec0, vecLow);
curVec0 = vminq(curVec0, vecHigh);
vstrhq_p(pDst, curVec0, p0);
}
}
#else
void arm_clip_q15(const q15_t * pSrc,
q15_t * pDst,
q15_t low,
q15_t high,
uint32_t numSamples)
{
uint32_t i;
for (i = 0; i < numSamples; i++)
{
if (pSrc[i] > high)
pDst[i] = high;
else if (pSrc[i] < low)
pDst[i] = low;
else
pDst[i] = pSrc[i];
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicClip group
*/
@@ -0,0 +1,134 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_clip_q31.c
* Description: Floating-point vector addition
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicClip
@{
*/
/**
@brief Elementwise fixed-point clipping
@param[in] pSrc points to input values
@param[out] pDst points to output clipped values
@param[in] low lower bound
@param[in] high higher bound
@param[in] numSamples number of samples to clip
@return none
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_clip_q31(const q31_t * pSrc,
q31_t * pDst,
q31_t low,
q31_t high,
uint32_t numSamples)
{
uint32_t blkCnt;
q31x4_t curVec0, curVec1;
q31x4_t vecLow, vecHigh;
vecLow = vdupq_n_s32(low);
vecHigh = vdupq_n_s32(high);
curVec0 = vld1q(pSrc);
pSrc += 4;
/*
* unrolled x 2 to allow
* vldr/vstr/vmin/vmax
* stall free interleaving
*/
blkCnt = numSamples >> 3;
while (blkCnt--)
{
curVec0 = vmaxq(curVec0, vecLow);
curVec1 = vld1q(pSrc);
pSrc += 4;
curVec0 = vminq(curVec0, vecHigh);
vst1q(pDst, curVec0);
pDst += 4;
curVec1 = vmaxq(curVec1, vecLow);
curVec0 = vld1q(pSrc);
pSrc += 4;
curVec1 = vminq(curVec1, vecHigh);
vst1q(pDst, curVec1);
pDst += 4;
}
/*
* Tail handling
*/
blkCnt = numSamples - ((numSamples >> 3) << 3);
if (blkCnt >= 4)
{
curVec0 = vmaxq(curVec0, vecLow);
curVec0 = vminq(curVec0, vecHigh);
vst1q(pDst, curVec0);
pDst += 4;
curVec0 = vld1q(pSrc);
pSrc += 4;
}
if (blkCnt > 0)
{
mve_pred16_t p0 = vctp32q(blkCnt & 3);
curVec0 = vmaxq(curVec0, vecLow);
curVec0 = vminq(curVec0, vecHigh);
vstrwq_p(pDst, curVec0, p0);
}
}
#else
void arm_clip_q31(const q31_t * pSrc,
q31_t * pDst,
q31_t low,
q31_t high,
uint32_t numSamples)
{
uint32_t i;
for (i = 0; i < numSamples; i++)
{
if (pSrc[i] > high)
pDst[i] = high;
else if (pSrc[i] < low)
pDst[i] = low;
else
pDst[i] = pSrc[i];
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicClip group
*/
@@ -0,0 +1,134 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_clip_q7.c
* Description: Floating-point vector addition
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicClip
@{
*/
/**
@brief Elementwise fixed-point clipping
@param[in] pSrc points to input values
@param[out] pDst points to output clipped values
@param[in] low lower bound
@param[in] high higher bound
@param[in] numSamples number of samples to clip
@return none
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_clip_q7(const q7_t * pSrc,
q7_t * pDst,
q7_t low,
q7_t high,
uint32_t numSamples)
{
uint32_t blkCnt;
q7x16_t curVec0, curVec1;
q7x16_t vecLow, vecHigh;
vecLow = vdupq_n_s8(low);
vecHigh = vdupq_n_s8(high);
curVec0 = vld1q(pSrc);
pSrc += 16;
/*
* unrolled x 2 to allow
* vldr/vstr/vmin/vmax
* stall free interleaving
*/
blkCnt = numSamples >> 5;
while (blkCnt--)
{
curVec0 = vmaxq(curVec0, vecLow);
curVec1 = vld1q(pSrc);
pSrc += 16;
curVec0 = vminq(curVec0, vecHigh);
vst1q(pDst, curVec0);
pDst += 16;
curVec1 = vmaxq(curVec1, vecLow);
curVec0 = vld1q(pSrc);
pSrc += 16;
curVec1 = vminq(curVec1, vecHigh);
vst1q(pDst, curVec1);
pDst += 16;
}
/*
* Tail handling
*/
blkCnt = numSamples - ((numSamples >> 5) << 5);
if (blkCnt >= 16)
{
curVec0 = vmaxq(curVec0, vecLow);
curVec0 = vminq(curVec0, vecHigh);
vst1q(pDst, curVec0);
pDst += 16;
curVec0 = vld1q(pSrc);
pSrc += 16;
}
if (blkCnt > 0)
{
mve_pred16_t p0 = vctp8q(blkCnt & 0xf);
curVec0 = vmaxq(curVec0, vecLow);
curVec0 = vminq(curVec0, vecHigh);
vstrbq_p(pDst, curVec0, p0);
}
}
#else
void arm_clip_q7(const q7_t * pSrc,
q7_t * pDst,
q7_t low,
q7_t high,
uint32_t numSamples)
{
uint32_t i;
for (i = 0; i < numSamples; i++)
{
if (pSrc[i] > high)
pDst[i] = high;
else if (pSrc[i] < low)
pDst[i] = low;
else
pDst[i] = pSrc[i];
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicClip group
*/
@@ -0,0 +1,228 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_dot_prod_f32.c
* Description: Floating-point dot product
*
* $Date: 05 October 2021
* $Revision: V1.9.1
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup BasicDotProd Vector Dot Product
Computes the dot product of two vectors.
The vectors are multiplied element-by-element and then summed.
<pre>
sum = pSrcA[0]*pSrcB[0] + pSrcA[1]*pSrcB[1] + ... + pSrcA[blockSize-1]*pSrcB[blockSize-1]
</pre>
There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
@addtogroup BasicDotProd
@{
*/
/**
@brief Dot product of floating-point vectors.
@param[in] pSrcA points to the first input vector.
@param[in] pSrcB points to the second input vector.
@param[in] blockSize number of samples in each vector.
@param[out] result output result returned here.
@return none
*/
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_dot_prod_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
uint32_t blockSize,
float32_t * result)
{
f32x4_t vecA, vecB;
f32x4_t vecSum;
uint32_t blkCnt;
float32_t sum = 0.0f;
vecSum = vdupq_n_f32(0.0f);
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/*
* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1]
* Calculate dot product and then store the result in a temporary buffer.
* and advance vector source and destination pointers
*/
vecA = vld1q(pSrcA);
pSrcA += 4;
vecB = vld1q(pSrcB);
pSrcB += 4;
vecSum = vfmaq(vecSum, vecA, vecB);
/*
* Decrement the blockSize loop counter
*/
blkCnt --;
}
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
mve_pred16_t p0 = vctp32q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vecSum = vfmaq_m(vecSum, vecA, vecB, p0);
}
sum = vecAddAcrossF32Mve(vecSum);
/* Store result in destination buffer */
*result = sum;
}
#else
void arm_dot_prod_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
uint32_t blockSize,
float32_t * result)
{
uint32_t blkCnt; /* Loop counter */
float32_t sum = 0.0f; /* Temporary return variable */
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
f32x4_t vec1;
f32x4_t vec2;
f32x4_t accum = vdupq_n_f32(0);
#if !defined(__aarch64__)
f32x2_t tmp = vdup_n_f32(0);
#endif
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
vec1 = vld1q_f32(pSrcA);
vec2 = vld1q_f32(pSrcB);
while (blkCnt > 0U)
{
/* C = A[0]*B[0] + A[1]*B[1] + A[2]*B[2] + ... + A[blockSize-1]*B[blockSize-1] */
/* Calculate dot product and then store the result in a temporary buffer. */
accum = vmlaq_f32(accum, vec1, vec2);
/* Increment pointers */
pSrcA += 4;
pSrcB += 4;
vec1 = vld1q_f32(pSrcA);
vec2 = vld1q_f32(pSrcB);
/* Decrement the loop counter */
blkCnt--;
}
#if defined(__aarch64__)
sum = vpadds_f32(vpadd_f32(vget_low_f32(accum), vget_high_f32(accum)));
#else
tmp = vpadd_f32(vget_low_f32(accum), vget_high_f32(accum));
sum = vget_lane_f32(tmp, 0) + vget_lane_f32(tmp, 1);
#endif
/* Tail */
blkCnt = blockSize & 0x3;
#else
#if defined (ARM_MATH_LOOPUNROLL) && !defined(ARM_MATH_AUTOVECTORIZE)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
/* Calculate dot product and store result in a temporary buffer. */
sum += (*pSrcA++) * (*pSrcB++);
sum += (*pSrcA++) * (*pSrcB++);
sum += (*pSrcA++) * (*pSrcB++);
sum += (*pSrcA++) * (*pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
#endif /* #if defined(ARM_MATH_NEON) */
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
/* Calculate dot product and store result in a temporary buffer. */
sum += (*pSrcA++) * (*pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
/* Store result in destination buffer */
*result = sum;
}
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
/**
@} end of BasicDotProd group
*/
@@ -0,0 +1,78 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_dot_prod_f64.c
* Description: Floating-point dot product
*
* $Date: 13 September 2021
* $Revision: V1.10.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicDotProd
@{
*/
/**
@brief Dot product of floating-point vectors.
@param[in] pSrcA points to the first input vector.
@param[in] pSrcB points to the second input vector.
@param[in] blockSize number of samples in each vector.
@param[out] result output result returned here.
@return none
*/
void arm_dot_prod_f64(
const float64_t * pSrcA,
const float64_t * pSrcB,
uint32_t blockSize,
float64_t * result)
{
uint32_t blkCnt; /* Loop counter */
float64_t sum = 0.; /* Temporary return variable */
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
/* Calculate dot product and store result in a temporary buffer. */
sum += (*pSrcA++) * (*pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
/* Store result in destination buffer */
*result = sum;
}
/**
@} end of BasicDotProd group
*/
@@ -0,0 +1,172 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_dot_prod_q15.c
* Description: Q15 dot product
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicDotProd
@{
*/
/**
@brief Dot product of Q15 vectors.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[in] blockSize number of samples in each vector
@param[out] result output result returned here
@return none
@par Scaling and Overflow Behavior
The intermediate multiplications are in 1.15 x 1.15 = 2.30 format and these
results are added to a 64-bit accumulator in 34.30 format.
Nonsaturating additions are used and given that there are 33 guard bits in the accumulator
there is no risk of overflow.
The return result is in 34.30 format.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_dot_prod_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
uint32_t blockSize,
q63_t * result)
{
uint32_t blkCnt; /* loop counters */
q15x8_t vecA;
q15x8_t vecB;
q63_t sum = 0LL;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
/*
* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1]
* Calculate dot product and then store the result in a temporary buffer.
*/
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
sum = vmlaldavaq(sum, vecA, vecB);
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrcA += 8;
pSrcB += 8;
}
/*
* tail
*/
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
sum = vmlaldavaq_p(sum, vecA, vecB, p0);
}
*result = sum;
}
#else
void arm_dot_prod_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
uint32_t blockSize,
q63_t * result)
{
uint32_t blkCnt; /* Loop counter */
q63_t sum = 0; /* Temporary return variable */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
#if defined (ARM_MATH_DSP)
/* Calculate dot product and store result in a temporary buffer. */
sum = __SMLALD(read_q15x2_ia (&pSrcA), read_q15x2_ia (&pSrcB), sum);
sum = __SMLALD(read_q15x2_ia (&pSrcA), read_q15x2_ia (&pSrcB), sum);
#else
sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++);
sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++);
sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++);
sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
/* Calculate dot product and store result in a temporary buffer. */
//#if defined (ARM_MATH_DSP)
// sum = __SMLALD(*pSrcA++, *pSrcB++, sum);
//#else
sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++);
//#endif
/* Decrement loop counter */
blkCnt--;
}
/* Store result in destination buffer in 34.30 format */
*result = sum;
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicDotProd group
*/
@@ -0,0 +1,174 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_dot_prod_q31.c
* Description: Q31 dot product
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicDotProd
@{
*/
/**
@brief Dot product of Q31 vectors.
@param[in] pSrcA points to the first input vector.
@param[in] pSrcB points to the second input vector.
@param[in] blockSize number of samples in each vector.
@param[out] result output result returned here.
@return none
@par Scaling and Overflow Behavior
The intermediate multiplications are in 1.31 x 1.31 = 2.62 format and these
are truncated to 2.48 format by discarding the lower 14 bits.
The 2.48 result is then added without saturation to a 64-bit accumulator in 16.48 format.
There are 15 guard bits in the accumulator and there is no risk of overflow as long as
the length of the vectors is less than 2^16 elements.
The return result is in 16.48 format.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_dot_prod_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
uint32_t blockSize,
q63_t * result)
{
uint32_t blkCnt; /* loop counters */
q31x4_t vecA;
q31x4_t vecB;
q63_t sum = 0LL;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
/*
* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1]
* Calculate dot product and then store the result in a temporary buffer.
*/
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
sum = vrmlaldavhaq(sum, vecA, vecB);
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrcA += 4;
pSrcB += 4;
}
/*
* tail
*/
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
sum = vrmlaldavhaq_p(sum, vecA, vecB, p0);
}
/*
* vrmlaldavhaq provides extra intermediate accumulator headroom.
* limiting the need of intermediate scaling
* Scalar variant uses 2.48 accu format by right shifting accumulators by 14.
* 16.48 output conversion is performed outside the loop by scaling accu. by 6
*/
*result = asrl(sum, (14 - 8));
}
#else
void arm_dot_prod_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
uint32_t blockSize,
q63_t * result)
{
uint32_t blkCnt; /* Loop counter */
q63_t sum = 0; /* Temporary return variable */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
/* Calculate dot product and store result in a temporary buffer. */
sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U;
sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U;
sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U;
sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
/* Calculate dot product and store result in a temporary buffer. */
sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U;
/* Decrement loop counter */
blkCnt--;
}
/* Store result in destination buffer in 16.48 format */
*result = sum;
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicDotProd group
*/
@@ -0,0 +1,191 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_dot_prod_q7.c
* Description: Q7 dot product
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicDotProd
@{
*/
/**
@brief Dot product of Q7 vectors.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[in] blockSize number of samples in each vector
@param[out] result output result returned here
@return none
@par Scaling and Overflow Behavior
The intermediate multiplications are in 1.7 x 1.7 = 2.14 format and these
results are added to an accumulator in 18.14 format.
Nonsaturating additions are used and there is no danger of wrap around as long as
the vectors are less than 2^18 elements long.
The return result is in 18.14 format.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_dot_prod_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
uint32_t blockSize,
q31_t * result)
{
uint32_t blkCnt; /* loop counters */
q7x16_t vecA;
q7x16_t vecB;
q31_t sum = 0;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4;
while (blkCnt > 0U)
{
/*
* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1]
* Calculate dot product and then store the result in a temporary buffer.
*/
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
sum = vmladavaq(sum, vecA, vecB);
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrcA += 16;
pSrcB += 16;
}
/*
* tail
*/
blkCnt = blockSize & 0xF;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp8q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
sum = vmladavaq_p(sum, vecA, vecB, p0);
}
*result = sum;
}
#else
void arm_dot_prod_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
uint32_t blockSize,
q31_t * result)
{
uint32_t blkCnt; /* Loop counter */
q31_t sum = 0; /* Temporary return variable */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q31_t input1, input2; /* Temporary variables */
q31_t inA1, inA2, inB1, inB2; /* Temporary variables */
#endif
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
#if defined (ARM_MATH_DSP)
/* read 4 samples at a time from sourceA */
input1 = read_q7x4_ia (&pSrcA);
/* read 4 samples at a time from sourceB */
input2 = read_q7x4_ia (&pSrcB);
/* extract two q7_t samples to q15_t samples */
inA1 = __SXTB16(__ROR(input1, 8));
/* extract reminaing two samples */
inA2 = __SXTB16(input1);
/* extract two q7_t samples to q15_t samples */
inB1 = __SXTB16(__ROR(input2, 8));
/* extract reminaing two samples */
inB2 = __SXTB16(input2);
/* multiply and accumulate two samples at a time */
sum = __SMLAD(inA1, inB1, sum);
sum = __SMLAD(inA2, inB2, sum);
#else
sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++);
sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++);
sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++);
sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
/* Calculate dot product and store result in a temporary buffer. */
//#if defined (ARM_MATH_DSP)
// sum = __SMLAD(*pSrcA++, *pSrcB++, sum);
//#else
sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++);
//#endif
/* Decrement loop counter */
blkCnt--;
}
/* Store result in destination buffer in 18.14 format */
*result = sum;
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicDotProd group
*/
@@ -0,0 +1,200 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mult_f32.c
* Description: Floating-point vector multiplication
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup BasicMult Vector Multiplication
Element-by-element multiplication of two vectors.
<pre>
pDst[n] = pSrcA[n] * pSrcB[n], 0 <= n < blockSize.
</pre>
There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
@addtogroup BasicMult
@{
*/
/**
@brief Floating-point vector multiplication.
@param[in] pSrcA points to the first input vector.
@param[in] pSrcB points to the second input vector.
@param[out] pDst points to the output vector.
@param[in] blockSize number of samples in each vector.
@return none
*/
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_mult_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
f32x4_t vec1;
f32x4_t vec2;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + B */
/* Add and then store the results in the destination buffer. */
vec1 = vld1q(pSrcA);
vec2 = vld1q(pSrcB);
res = vmulq(vec1, vec2);
vst1q(pDst, res);
/* Increment pointers */
pSrcA += 4;
pSrcB += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
if (blkCnt > 0U)
{
/* C = A + B */
mve_pred16_t p0 = vctp32q(blkCnt);
vec1 = vld1q(pSrcA);
vec2 = vld1q(pSrcB);
vstrwq_p(pDst, vmulq(vec1,vec2), p0);
}
}
#else
void arm_mult_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
f32x4_t vec1;
f32x4_t vec2;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A * B */
/* Multiply the inputs and then store the results in the destination buffer. */
vec1 = vld1q_f32(pSrcA);
vec2 = vld1q_f32(pSrcB);
res = vmulq_f32(vec1, vec2);
vst1q_f32(pDst, res);
/* Increment pointers */
pSrcA += 4;
pSrcB += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
#else
#if defined (ARM_MATH_LOOPUNROLL) && !defined(ARM_MATH_AUTOVECTORIZE)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A * B */
/* Multiply inputs and store result in destination buffer. */
*pDst++ = (*pSrcA++) * (*pSrcB++);
*pDst++ = (*pSrcA++) * (*pSrcB++);
*pDst++ = (*pSrcA++) * (*pSrcB++);
*pDst++ = (*pSrcA++) * (*pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
#endif /* #if defined(ARM_MATH_NEON) */
while (blkCnt > 0U)
{
/* C = A * B */
/* Multiply input and store result in destination buffer. */
*pDst++ = (*pSrcA++) * (*pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
/**
@} end of BasicMult group
*/
@@ -0,0 +1,75 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mult_f64.c
* Description: Floating-point vector multiplication
*
* $Date: 13 September 2021
* $Revision: V1.10.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicMult
@{
*/
/**
@brief Floating-point vector multiplication.
@param[in] pSrcA points to the first input vector.
@param[in] pSrcB points to the second input vector.
@param[out] pDst points to the output vector.
@param[in] blockSize number of samples in each vector.
@return none
*/
void arm_mult_f64(
const float64_t * pSrcA,
const float64_t * pSrcB,
float64_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
while (blkCnt > 0U)
{
/* C = A * B */
/* Multiply input and store result in destination buffer. */
*pDst++ = (*pSrcA++) * (*pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
}
/**
@} end of BasicMult group
*/
@@ -0,0 +1,192 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mult_q15.c
* Description: Q15 vector multiplication
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicMult
@{
*/
/**
@brief Q15 vector multiplication
@param[in] pSrcA points to first input vector
@param[in] pSrcB points to second input vector
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_mult_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q15x8_t vecA, vecB;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
/*
* C = A * B
* Multiply the inputs and then store the results in the destination buffer.
*/
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vst1q(pDst, vqdmulhq(vecA, vecB));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrcA += 8;
pSrcB += 8;
pDst += 8;
}
/*
* tail
*/
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vstrhq_p(pDst, vqdmulhq(vecA, vecB), p0);
}
}
#else
void arm_mult_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q31_t inA1, inA2, inB1, inB2; /* Temporary input variables */
q15_t out1, out2, out3, out4; /* Temporary output variables */
q31_t mul1, mul2, mul3, mul4; /* Temporary variables */
#endif
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A * B */
#if defined (ARM_MATH_DSP)
/* read 2 samples at a time from sourceA */
inA1 = read_q15x2_ia (&pSrcA);
/* read 2 samples at a time from sourceB */
inB1 = read_q15x2_ia (&pSrcB);
/* read 2 samples at a time from sourceA */
inA2 = read_q15x2_ia (&pSrcA);
/* read 2 samples at a time from sourceB */
inB2 = read_q15x2_ia (&pSrcB);
/* multiply mul = sourceA * sourceB */
mul1 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1 >> 16));
mul2 = (q31_t) ((q15_t) (inA1 ) * (q15_t) (inB1 ));
mul3 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) (inB2 >> 16));
mul4 = (q31_t) ((q15_t) (inA2 ) * (q15_t) (inB2 ));
/* saturate result to 16 bit */
out1 = (q15_t) __SSAT(mul1 >> 15, 16);
out2 = (q15_t) __SSAT(mul2 >> 15, 16);
out3 = (q15_t) __SSAT(mul3 >> 15, 16);
out4 = (q15_t) __SSAT(mul4 >> 15, 16);
/* store result to destination */
#ifndef ARM_MATH_BIG_ENDIAN
write_q15x2_ia (&pDst, __PKHBT(out2, out1, 16));
write_q15x2_ia (&pDst, __PKHBT(out4, out3, 16));
#else
write_q15x2_ia (&pDst, __PKHBT(out1, out2, 16));
write_q15x2_ia (&pDst, __PKHBT(out3, out4, 16));
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
#else
*pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16);
*pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16);
*pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16);
*pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A * B */
/* Multiply inputs and store result in destination buffer. */
*pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16);
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicMult group
*/
@@ -0,0 +1,168 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mult_q31.c
* Description: Q31 vector multiplication
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicMult
@{
*/
/**
@brief Q31 vector multiplication.
@param[in] pSrcA points to the first input vector.
@param[in] pSrcB points to the second input vector.
@param[out] pDst points to the output vector.
@param[in] blockSize number of samples in each vector.
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_mult_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q31x4_t vecA, vecB;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
/*
* C = A * B
* Multiply the inputs and then store the results in the destination buffer.
*/
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vst1q(pDst, vqdmulhq(vecA, vecB));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrcA += 4;
pSrcB += 4;
pDst += 4;
}
/*
* tail
*/
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vstrwq_p(pDst, vqdmulhq(vecA, vecB), p0);
}
}
#else
void arm_mult_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
q31_t out; /* Temporary output variable */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A * B */
/* Multiply inputs and store result in destination buffer. */
out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32;
out = __SSAT(out, 31);
*pDst++ = out << 1U;
out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32;
out = __SSAT(out, 31);
*pDst++ = out << 1U;
out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32;
out = __SSAT(out, 31);
*pDst++ = out << 1U;
out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32;
out = __SSAT(out, 31);
*pDst++ = out << 1U;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A * B */
/* Multiply inputs and store result in destination buffer. */
out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32;
out = __SSAT(out, 31);
*pDst++ = out << 1U;
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicMult group
*/
@@ -0,0 +1,168 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mult_q7.c
* Description: Q7 vector multiplication
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicMult
@{
*/
/**
@brief Q7 vector multiplication
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q7 range [0x80 0x7F] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_mult_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q7x16_t vecA, vecB;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4;
while (blkCnt > 0U)
{
/*
* C = A * B
* Multiply the inputs and then store the results in the destination buffer.
*/
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vst1q(pDst, vqdmulhq(vecA, vecB));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrcA += 16;
pSrcB += 16;
pDst += 16;
}
/*
* tail
*/
blkCnt = blockSize & 0xF;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp8q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vstrbq_p(pDst, vqdmulhq(vecA, vecB), p0);
}
}
#else
void arm_mult_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q7_t out1, out2, out3, out4; /* Temporary output variables */
#endif
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A * B */
#if defined (ARM_MATH_DSP)
/* Multiply inputs and store results in temporary variables */
out1 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
out2 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
out3 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
out4 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
/* Pack and store result in destination buffer (in single write) */
write_q7x4_ia (&pDst, __PACKq7(out1, out2, out3, out4));
#else
*pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
*pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
*pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
*pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A * B */
/* Multiply input and store result in destination buffer. */
*pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicMult group
*/
@@ -0,0 +1,192 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_negate_f32.c
* Description: Negates floating-point vectors
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup BasicNegate Vector Negate
Negates the elements of a vector.
<pre>
pDst[n] = -pSrc[n], 0 <= n < blockSize.
</pre>
The functions support in-place computation allowing the source and
destination pointers to reference the same memory buffer.
There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
@addtogroup BasicNegate
@{
*/
/**
@brief Negates the elements of a floating-point vector.
@param[in] pSrc points to input vector.
@param[out] pDst points to output vector.
@param[in] blockSize number of samples in each vector.
@return none
*/
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_negate_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
f32x4_t vec1;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = |A| */
/* Calculate absolute values and then store the results in the destination buffer. */
vec1 = vld1q(pSrc);
res = vnegq(vec1);
vst1q(pDst, res);
/* Increment pointers */
pSrc += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
if (blkCnt > 0U)
{
/* C = |A| */
mve_pred16_t p0 = vctp32q(blkCnt);
vec1 = vld1q((float32_t const *) pSrc);
vstrwq_p(pDst, vnegq(vec1), p0);
}
}
#else
void arm_negate_f32(
const float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_NEON_EXPERIMENTAL) && !defined(ARM_MATH_AUTOVECTORIZE)
f32x4_t vec1;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = -A */
/* Negate and then store the results in the destination buffer. */
vec1 = vld1q_f32(pSrc);
res = vnegq_f32(vec1);
vst1q_f32(pDst, res);
/* Increment pointers */
pSrc += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
#else
#if defined (ARM_MATH_LOOPUNROLL) && !defined(ARM_MATH_AUTOVECTORIZE)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = -A */
/* Negate and store result in destination buffer. */
*pDst++ = -*pSrc++;
*pDst++ = -*pSrc++;
*pDst++ = -*pSrc++;
*pDst++ = -*pSrc++;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
#endif /* #if defined(ARM_MATH_NEON_EXPERIMENTAL) */
while (blkCnt > 0U)
{
/* C = -A */
/* Negate and store result in destination buffer. */
*pDst++ = -*pSrc++;
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
/**
@} end of BasicNegate group
*/
@@ -0,0 +1,73 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_negate_f64.c
* Description: Negates floating-point vectors
*
* $Date: 13 September 2021
* $Revision: V1.10.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicNegate
@{
*/
/**
@brief Negates the elements of a floating-point vector.
@param[in] pSrc points to input vector.
@param[out] pDst points to output vector.
@param[in] blockSize number of samples in each vector.
@return none
*/
void arm_negate_f64(
const float64_t * pSrc,
float64_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
while (blkCnt > 0U)
{
/* C = -A */
/* Negate and store result in destination buffer. */
*pDst++ = -*pSrc++;
/* Decrement loop counter */
blkCnt--;
}
}
/**
@} end of BasicNegate group
*/
@@ -0,0 +1,171 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_negate_q15.c
* Description: Negates Q15 vectors
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicNegate
@{
*/
/**
@brief Negates the elements of a Q15 vector.
@param[in] pSrc points to the input vector.
@param[out] pDst points to the output vector.
@param[in] blockSize number of samples in each vector.
@return none
@par Conditions for optimum performance
Input and output buffers should be aligned by 32-bit
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
The Q15 value -1 (0x8000) is saturated to the maximum allowable positive value 0x7FFF.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_negate_q15(
const q15_t * pSrc,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q15x8_t vecSrc;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
/*
* C = -A
* Negate and then store the results in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vst1q(pDst, vqnegq(vecSrc));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 8;
pDst += 8;
}
/*
* tail
*/
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecSrc = vld1q(pSrc);
vstrhq_p(pDst, vqnegq(vecSrc), p0);
}
}
#else
void arm_negate_q15(
const q15_t * pSrc,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
q15_t in; /* Temporary input variable */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q31_t in1; /* Temporary input variables */
#endif
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = -A */
#if defined (ARM_MATH_DSP)
/* Negate and store result in destination buffer (2 samples at a time). */
in1 = read_q15x2_ia (&pSrc);
write_q15x2_ia (&pDst, __QSUB16(0, in1));
in1 = read_q15x2_ia (&pSrc);
write_q15x2_ia (&pDst, __QSUB16(0, in1));
#else
in = *pSrc++;
*pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in;
in = *pSrc++;
*pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in;
in = *pSrc++;
*pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in;
in = *pSrc++;
*pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in;
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = -A */
/* Negate and store result in destination buffer. */
in = *pSrc++;
*pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in;
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicNegate group
*/
@@ -0,0 +1,178 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_negate_q31.c
* Description: Negates Q31 vectors
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicNegate
@{
*/
/**
@brief Negates the elements of a Q31 vector.
@param[in] pSrc points to the input vector.
@param[out] pDst points to the output vector.
@param[in] blockSize number of samples in each vector.
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
The Q31 value -1 (0x80000000) is saturated to the maximum allowable positive value 0x7FFFFFFF.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_negate_q31(
const q31_t * pSrc,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q31x4_t vecSrc;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
/*
* C = -A
* Negate and then store the results in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vst1q(pDst, vqnegq(vecSrc));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 4;
pDst += 4;
}
/*
* tail
*/
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecSrc = vld1q(pSrc);
vstrwq_p(pDst, vqnegq(vecSrc), p0);
}
}
#else
void arm_negate_q31(
const q31_t * pSrc,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
q31_t in; /* Temporary input variable */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = -A */
/* Negate and store result in destination buffer. */
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = __QSUB(0, in);
#else
*pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
#endif
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = __QSUB(0, in);
#else
*pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
#endif
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = __QSUB(0, in);
#else
*pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
#endif
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = __QSUB(0, in);
#else
*pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = -A */
/* Negate and store result in destination buffer. */
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = __QSUB(0, in);
#else
*pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
#endif
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicNegate group
*/
@@ -0,0 +1,171 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_negate_q7.c
* Description: Negates Q7 vectors
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicNegate
@{
*/
/**
@brief Negates the elements of a Q7 vector.
@param[in] pSrc points to the input vector.
@param[out] pDst points to the output vector.
@param[in] blockSize number of samples in each vector.
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
The Q7 value -1 (0x80) is saturated to the maximum allowable positive value 0x7F.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_negate_q7(
const q7_t * pSrc,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q7x16_t vecSrc;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4;
while (blkCnt > 0U)
{
/*
* C = -A
* Negate and then store the results in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vst1q(pDst, vqnegq(vecSrc));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 16;
pDst += 16;
}
/*
* tail
*/
blkCnt = blockSize & 0xF;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp8q(blkCnt);
vecSrc = vld1q(pSrc);
vstrbq_p(pDst, vqnegq(vecSrc), p0);
}
}
#else
void arm_negate_q7(
const q7_t * pSrc,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
q7_t in; /* Temporary input variable */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q31_t in1; /* Temporary input variable */
#endif
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = -A */
#if defined (ARM_MATH_DSP)
/* Negate and store result in destination buffer (4 samples at a time). */
in1 = read_q7x4_ia (&pSrc);
write_q7x4_ia (&pDst, __QSUB8(0, in1));
#else
in = *pSrc++;
*pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in;
in = *pSrc++;
*pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in;
in = *pSrc++;
*pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in;
in = *pSrc++;
*pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in;
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = -A */
/* Negate and store result in destination buffer. */
in = *pSrc++;
#if defined (ARM_MATH_DSP)
*pDst++ = (q7_t) __QSUB8(0, in);
#else
*pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in;
#endif
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicNegate group
*/
@@ -0,0 +1,130 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_not_u16.c
* Description: uint16_t bitwise NOT
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup Not Vector bitwise NOT
Compute the logical bitwise NOT.
There are separate functions for uint32_t, uint16_t, and uint8_t data types.
*/
/**
@addtogroup Not
@{
*/
/**
@brief Compute the logical bitwise NOT of a fixed-point vector.
@param[in] pSrc points to input vector
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_not_u16(
const uint16_t * pSrc,
uint16_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
uint16x8_t vecSrc;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
vecSrc = vld1q(pSrc);
vst1q(pDst, vmvnq_u16(vecSrc) );
pSrc += 8;
pDst += 8;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecSrc = vld1q(pSrc);
vstrhq_p(pDst, vmvnq_u16(vecSrc), p0);
}
#else
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
uint16x8_t inV;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3U;
while (blkCnt > 0U)
{
inV = vld1q_u16(pSrc);
vst1q_u16(pDst, vmvnq_u16(inV) );
pSrc += 8;
pDst += 8;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 7;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif
while (blkCnt > 0U)
{
*pDst++ = ~(*pSrc++);
/* Decrement the loop counter */
blkCnt--;
}
#endif /* if defined(ARM_MATH_MVEI) */
}
/**
@} end of Not group
*/
@@ -0,0 +1,122 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_not_u32.c
* Description: uint32_t bitwise NOT
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup Not
@{
*/
/**
@brief Compute the logical bitwise NOT of a fixed-point vector.
@param[in] pSrc points to input vector
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_not_u32(
const uint32_t * pSrc,
uint32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
uint32x4_t vecSrc;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
vecSrc = vld1q(pSrc);
vst1q(pDst, vmvnq_u32(vecSrc) );
pSrc += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecSrc = vld1q(pSrc);
vstrwq_p(pDst, vmvnq_u32(vecSrc), p0);
}
#else
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
uint32x4_t inV;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
inV = vld1q_u32(pSrc);
vst1q_u32(pDst, vmvnq_u32(inV) );
pSrc += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 3;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif
while (blkCnt > 0U)
{
*pDst++ = ~(*pSrc++);
/* Decrement the loop counter */
blkCnt--;
}
#endif /* if defined(ARM_MATH_MVEI) */
}
/**
@} end of Not group
*/
@@ -0,0 +1,122 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_not_u8.c
* Description: uint8_t bitwise NOT
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup Not
@{
*/
/**
@brief Compute the logical bitwise NOT of a fixed-point vector.
@param[in] pSrc points to input vector
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_not_u8(
const uint8_t * pSrc,
uint8_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
uint8x16_t vecSrc;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4;
while (blkCnt > 0U)
{
vecSrc = vld1q(pSrc);
vst1q(pDst, vmvnq_u8(vecSrc) );
pSrc += 16;
pDst += 16;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0xF;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp8q(blkCnt);
vecSrc = vld1q(pSrc);
vstrbq_p(pDst, vmvnq_u8(vecSrc), p0);
}
#else
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
uint8x16_t inV;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4U;
while (blkCnt > 0U)
{
inV = vld1q_u8(pSrc);
vst1q_u8(pDst, vmvnq_u8(inV) );
pSrc += 16;
pDst += 16;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0xF;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif
while (blkCnt > 0U)
{
*pDst++ = ~(*pSrc++);
/* Decrement the loop counter */
blkCnt--;
}
#endif /* if defined(ARM_MATH_MVEI) */
}
/**
@} end of Not group
*/
@@ -0,0 +1,196 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_offset_f32.c
* Description: Floating-point vector offset
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup BasicOffset Vector Offset
Adds a constant offset to each element of a vector.
<pre>
pDst[n] = pSrc[n] + offset, 0 <= n < blockSize.
</pre>
The functions support in-place computation allowing the source and
destination pointers to reference the same memory buffer.
There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
@addtogroup BasicOffset
@{
*/
/**
@brief Adds a constant offset to a floating-point vector.
@param[in] pSrc points to the input vector
@param[in] offset is the offset to be added
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_offset_f32(
const float32_t * pSrc,
float32_t offset,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
f32x4_t vec1;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + offset */
/* Add offset and then store the results in the destination buffer. */
vec1 = vld1q(pSrc);
res = vaddq(vec1,offset);
vst1q(pDst, res);
/* Increment pointers */
pSrc += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vec1 = vld1q((float32_t const *) pSrc);
vstrwq_p(pDst, vaddq(vec1, offset), p0);
}
}
#else
void arm_offset_f32(
const float32_t * pSrc,
float32_t offset,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_NEON_EXPERIMENTAL) && !defined(ARM_MATH_AUTOVECTORIZE)
f32x4_t vec1;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + offset */
/* Add offset and then store the results in the destination buffer. */
vec1 = vld1q_f32(pSrc);
res = vaddq_f32(vec1,vdupq_n_f32(offset));
vst1q_f32(pDst, res);
/* Increment pointers */
pSrc += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
#else
#if defined (ARM_MATH_LOOPUNROLL) && !defined(ARM_MATH_AUTOVECTORIZE)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + offset */
/* Add offset and store result in destination buffer. */
*pDst++ = (*pSrc++) + offset;
*pDst++ = (*pSrc++) + offset;
*pDst++ = (*pSrc++) + offset;
*pDst++ = (*pSrc++) + offset;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
#endif /* #if defined(ARM_MATH_NEON_EXPERIMENTAL) */
while (blkCnt > 0U)
{
/* C = A + offset */
/* Add offset and store result in destination buffer. */
*pDst++ = (*pSrc++) + offset;
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
/**
@} end of BasicOffset group
*/
@@ -0,0 +1,75 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_offset_f64.c
* Description: Floating-point vector offset
*
* $Date: 13 September 2021
* $Revision: V1.10.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicOffset
@{
*/
/**
@brief Adds a constant offset to a floating-point vector.
@param[in] pSrc points to the input vector
@param[in] offset is the offset to be added
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_offset_f64(
const float64_t * pSrc,
float64_t offset,
float64_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
while (blkCnt > 0U)
{
/* C = A + offset */
/* Add offset and store result in destination buffer. */
*pDst++ = (*pSrc++) + offset;
/* Decrement loop counter */
blkCnt--;
}
}
/**
@} end of BasicOffset group
*/
@@ -0,0 +1,168 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_offset_q15.c
* Description: Q15 vector offset
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicOffset
@{
*/
/**
@brief Adds a constant offset to a Q15 vector.
@param[in] pSrc points to the input vector
@param[in] offset is the offset to be added
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_offset_q15(
const q15_t * pSrc,
q15_t offset,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q15x8_t vecSrc;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
/*
* C = A + offset
* Add offset and then store the result in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vst1q(pDst, vqaddq(vecSrc, offset));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 8;
pDst += 8;
}
/*
* tail
*/
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecSrc = vld1q(pSrc);
vstrhq_p(pDst, vqaddq(vecSrc, offset), p0);
}
}
#else
void arm_offset_q15(
const q15_t * pSrc,
q15_t offset,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q31_t offset_packed; /* Offset packed to 32 bit */
/* Offset is packed to 32 bit in order to use SIMD32 for addition */
offset_packed = __PKHBT(offset, offset, 16);
#endif
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + offset */
#if defined (ARM_MATH_DSP)
/* Add offset and store result in destination buffer (2 samples at a time). */
write_q15x2_ia (&pDst, __QADD16(read_q15x2_ia (&pSrc), offset_packed));
write_q15x2_ia (&pDst, __QADD16(read_q15x2_ia (&pSrc), offset_packed));
#else
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16);
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16);
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16);
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A + offset */
/* Add offset and store result in destination buffer. */
#if defined (ARM_MATH_DSP)
*pDst++ = (q15_t) __QADD16(*pSrc++, offset);
#else
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16);
#endif
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicOffset group
*/
@@ -0,0 +1,159 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_offset_q31.c
* Description: Q31 vector offset
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicOffset
@{
*/
/**
@brief Adds a constant offset to a Q31 vector.
@param[in] pSrc points to the input vector
@param[in] offset is the offset to be added
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_offset_q31(
const q31_t * pSrc,
q31_t offset,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q31x4_t vecSrc;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
/*
* C = A + offset
* Add offset and then store the result in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vst1q(pDst, vqaddq(vecSrc, offset));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 4;
pDst += 4;
}
/*
* tail
*/
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecSrc = vld1q(pSrc);
vstrwq_p(pDst, vqaddq(vecSrc, offset), p0);
}
}
#else
void arm_offset_q31(
const q31_t * pSrc,
q31_t offset,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + offset */
/* Add offset and store result in destination buffer. */
*pDst++ = __QADD(*pSrc++, offset);
*pDst++ = __QADD(*pSrc++, offset);
*pDst++ = __QADD(*pSrc++, offset);
*pDst++ = __QADD(*pSrc++, offset);
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A + offset */
/* Add offset and store result in destination buffer. */
#if defined (ARM_MATH_DSP)
*pDst++ = __QADD(*pSrc++, offset);
#else
*pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset);
#endif
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicOffset group
*/
@@ -0,0 +1,162 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_offset_q7.c
* Description: Q7 vector offset
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicOffset
@{
*/
/**
@brief Adds a constant offset to a Q7 vector.
@param[in] pSrc points to the input vector
@param[in] offset is the offset to be added
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q7 range [0x80 0x7F] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_offset_q7(
const q7_t * pSrc,
q7_t offset,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q7x16_t vecSrc;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4;
while (blkCnt > 0U)
{
/*
* C = A + offset
* Add offset and then store the result in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vst1q(pDst, vqaddq(vecSrc, offset));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 16;
pDst += 16;
}
/*
* tail
*/
blkCnt = blockSize & 0xF;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp8q(blkCnt);
vecSrc = vld1q(pSrc);
vstrbq_p(pDst, vqaddq(vecSrc, offset), p0);
}
}
#else
void arm_offset_q7(
const q7_t * pSrc,
q7_t offset,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q31_t offset_packed; /* Offset packed to 32 bit */
/* Offset is packed to 32 bit in order to use SIMD32 for addition */
offset_packed = __PACKq7(offset, offset, offset, offset);
#endif
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + offset */
#if defined (ARM_MATH_DSP)
/* Add offset and store result in destination buffer (4 samples at a time). */
write_q7x4_ia (&pDst, __QADD8(read_q7x4_ia (&pSrc), offset_packed));
#else
*pDst++ = (q7_t) __SSAT((q15_t) *pSrc++ + offset, 8);
*pDst++ = (q7_t) __SSAT((q15_t) *pSrc++ + offset, 8);
*pDst++ = (q7_t) __SSAT((q15_t) *pSrc++ + offset, 8);
*pDst++ = (q7_t) __SSAT((q15_t) *pSrc++ + offset, 8);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A + offset */
/* Add offset and store result in destination buffer. */
*pDst++ = (q7_t) __SSAT((q15_t) *pSrc++ + offset, 8);
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicOffset group
*/
@@ -0,0 +1,137 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_or_u16.c
* Description: uint16_t bitwise inclusive OR
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup Or Vector bitwise inclusive OR
Compute the logical bitwise OR.
There are separate functions for uint32_t, uint16_t, and uint8_t data types.
*/
/**
@addtogroup Or
@{
*/
/**
@brief Compute the logical bitwise OR of two fixed-point vectors.
@param[in] pSrcA points to input vector A
@param[in] pSrcB points to input vector B
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_or_u16(
const uint16_t * pSrcA,
const uint16_t * pSrcB,
uint16_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
uint16x8_t vecSrcA, vecSrcB;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vst1q(pDst, vorrq_u16(vecSrcA, vecSrcB) );
pSrcA += 8;
pSrcB += 8;
pDst += 8;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vstrhq_p(pDst, vorrq_u16(vecSrcA, vecSrcB), p0);
}
#else
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
uint16x8_t vecA, vecB;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3U;
while (blkCnt > 0U)
{
vecA = vld1q_u16(pSrcA);
vecB = vld1q_u16(pSrcB);
vst1q_u16(pDst, vorrq_u16(vecA, vecB) );
pSrcA += 8;
pSrcB += 8;
pDst += 8;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 7;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif
while (blkCnt > 0U)
{
*pDst++ = (*pSrcA++)|(*pSrcB++);
/* Decrement the loop counter */
blkCnt--;
}
#endif /* if defined(ARM_MATH_MVEI) */
}
/**
@} end of Or group
*/
@@ -0,0 +1,128 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_or_u32.c
* Description: uint32_t bitwise inclusive OR
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup Or
@{
*/
/**
@brief Compute the logical bitwise OR of two fixed-point vectors.
@param[in] pSrcA points to input vector A
@param[in] pSrcB points to input vector B
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_or_u32(
const uint32_t * pSrcA,
const uint32_t * pSrcB,
uint32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
uint32x4_t vecSrcA, vecSrcB;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vst1q(pDst, vorrq_u32(vecSrcA, vecSrcB) );
pSrcA += 4;
pSrcB += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vstrwq_p(pDst, vorrq_u32(vecSrcA, vecSrcB), p0);
}
#else
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
uint32x4_t vecA, vecB;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
vecA = vld1q_u32(pSrcA);
vecB = vld1q_u32(pSrcB);
vst1q_u32(pDst, vorrq_u32(vecA, vecB) );
pSrcA += 4;
pSrcB += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 3;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif
while (blkCnt > 0U)
{
*pDst++ = (*pSrcA++)|(*pSrcB++);
/* Decrement the loop counter */
blkCnt--;
}
#endif /* if defined(ARM_MATH_MVEI) */
}
/**
@} end of Or group
*/
@@ -0,0 +1,128 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_or_u8.c
* Description: uint8_t bitwise inclusive OR
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup Or
@{
*/
/**
@brief Compute the logical bitwise OR of two fixed-point vectors.
@param[in] pSrcA points to input vector A
@param[in] pSrcB points to input vector B
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_or_u8(
const uint8_t * pSrcA,
const uint8_t * pSrcB,
uint8_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
uint8x16_t vecSrcA, vecSrcB;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4;
while (blkCnt > 0U)
{
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vst1q(pDst, vorrq_u8(vecSrcA, vecSrcB) );
pSrcA += 16;
pSrcB += 16;
pDst += 16;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0xF;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp8q(blkCnt);
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vstrbq_p(pDst, vorrq_u8(vecSrcA, vecSrcB), p0);
}
#else
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
uint8x16_t vecA, vecB;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4U;
while (blkCnt > 0U)
{
vecA = vld1q_u8(pSrcA);
vecB = vld1q_u8(pSrcB);
vst1q_u8(pDst, vorrq_u8(vecA, vecB) );
pSrcA += 16;
pSrcB += 16;
pDst += 16;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0xF;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif
while (blkCnt > 0U)
{
*pDst++ = (*pSrcA++)|(*pSrcB++);
/* Decrement the loop counter */
blkCnt--;
}
#endif /* if defined(ARM_MATH_MVEI) */
}
/**
@} end of Or group
*/
@@ -0,0 +1,216 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_scale_f32.c
* Description: Multiplies a floating-point vector by a scalar
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup BasicScale Vector Scale
Multiply a vector by a scalar value. For floating-point data, the algorithm used is:
<pre>
pDst[n] = pSrc[n] * scale, 0 <= n < blockSize.
</pre>
In the fixed-point Q7, Q15, and Q31 functions, <code>scale</code> is represented by
a fractional multiplication <code>scaleFract</code> and an arithmetic shift <code>shift</code>.
The shift allows the gain of the scaling operation to exceed 1.0.
The algorithm used with fixed-point data is:
<pre>
pDst[n] = (pSrc[n] * scaleFract) << shift, 0 <= n < blockSize.
</pre>
The overall scale factor applied to the fixed-point data is
<pre>
scale = scaleFract * 2^shift.
</pre>
The functions support in-place computation allowing the source and destination
pointers to reference the same memory buffer.
*/
/**
@addtogroup BasicScale
@{
*/
/**
@brief Multiplies a floating-point vector by a scalar.
@param[in] pSrc points to the input vector
@param[in] scale scale factor to be applied
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_scale_f32(
const float32_t * pSrc,
float32_t scale,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
f32x4_t vec1;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + offset */
/* Add offset and then store the results in the destination buffer. */
vec1 = vld1q(pSrc);
res = vmulq(vec1,scale);
vst1q(pDst, res);
/* Increment pointers */
pSrc += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vec1 = vld1q((float32_t const *) pSrc);
vstrwq_p(pDst, vmulq(vec1, scale), p0);
}
}
#else
void arm_scale_f32(
const float32_t *pSrc,
float32_t scale,
float32_t *pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_NEON_EXPERIMENTAL)
f32x4_t vec1;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A * scale */
/* Scale the input and then store the results in the destination buffer. */
vec1 = vld1q_f32(pSrc);
res = vmulq_f32(vec1, vdupq_n_f32(scale));
vst1q_f32(pDst, res);
/* Increment pointers */
pSrc += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
#else
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
float32_t in1, in2, in3, in4;
/* C = A * scale */
/* Scale input and store result in destination buffer. */
in1 = (*pSrc++) * scale;
in2 = (*pSrc++) * scale;
in3 = (*pSrc++) * scale;
in4 = (*pSrc++) * scale;
*pDst++ = in1;
*pDst++ = in2;
*pDst++ = in3;
*pDst++ = in4;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
#endif /* #if defined(ARM_MATH_NEON_EXPERIMENTAL) */
while (blkCnt > 0U)
{
/* C = A * scale */
/* Scale input and store result in destination buffer. */
*pDst++ = (*pSrc++) * scale;
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
/**
@} end of BasicScale group
*/
@@ -0,0 +1,75 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_scale_f64.c
* Description: Multiplies a floating-point vector by a scalar
*
* $Date: 13 September 2021
* $Revision: V1.10.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicScale
@{
*/
/**
@brief Multiplies a floating-point vector by a scalar.
@param[in] pSrc points to the input vector
@param[in] scale scale factor to be applied
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_scale_f64(
const float64_t *pSrc,
float64_t scale,
float64_t *pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
while (blkCnt > 0U)
{
/* C = A * scale */
/* Scale input and store result in destination buffer. */
*pDst++ = (*pSrc++) * scale;
/* Decrement loop counter */
blkCnt--;
}
}
/**
@} end of BasicScale group
*/
@@ -0,0 +1,201 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_scale_q15.c
* Description: Multiplies a Q15 vector by a scalar
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicScale
@{
*/
/**
@brief Multiplies a Q15 vector by a scalar.
@param[in] pSrc points to the input vector
@param[in] scaleFract fractional portion of the scale value
@param[in] shift number of bits to shift the result by
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.15 format.
These are multiplied to yield a 2.30 intermediate result and this is shifted with saturation to 1.15 format.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_scale_q15(
const q15_t * pSrc,
q15_t scaleFract,
int8_t shift,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q15x8_t vecSrc;
q15x8_t vecDst;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
/*
* C = A * scale
* Scale the input and then store the result in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vecDst = vmulhq(vecSrc, vdupq_n_s16(scaleFract));
vecDst = vqshlq_r(vecDst, shift + 1);
vst1q(pDst, vecDst);
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 8;
pDst += 8;
}
/*
* tail
*/
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);;
vecSrc = vld1q(pSrc);
vecDst = vmulhq(vecSrc, vdupq_n_s16(scaleFract));
vecDst = vqshlq_r(vecDst, shift + 1);
vstrhq_p(pDst, vecDst, p0);
}
}
#else
void arm_scale_q15(
const q15_t *pSrc,
q15_t scaleFract,
int8_t shift,
q15_t *pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
int8_t kShift = 15 - shift; /* Shift to apply after scaling */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q31_t inA1, inA2;
q31_t out1, out2, out3, out4; /* Temporary output variables */
q15_t in1, in2, in3, in4; /* Temporary input variables */
#endif
#endif
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A * scale */
#if defined (ARM_MATH_DSP)
/* read 2 times 2 samples at a time from source */
inA1 = read_q15x2_ia (&pSrc);
inA2 = read_q15x2_ia (&pSrc);
/* Scale inputs and store result in temporary variables
* in single cycle by packing the outputs */
out1 = (q31_t) ((q15_t) (inA1 >> 16) * scaleFract);
out2 = (q31_t) ((q15_t) (inA1 ) * scaleFract);
out3 = (q31_t) ((q15_t) (inA2 >> 16) * scaleFract);
out4 = (q31_t) ((q15_t) (inA2 ) * scaleFract);
/* apply shifting */
out1 = out1 >> kShift;
out2 = out2 >> kShift;
out3 = out3 >> kShift;
out4 = out4 >> kShift;
/* saturate the output */
in1 = (q15_t) (__SSAT(out1, 16));
in2 = (q15_t) (__SSAT(out2, 16));
in3 = (q15_t) (__SSAT(out3, 16));
in4 = (q15_t) (__SSAT(out4, 16));
/* store result to destination */
write_q15x2_ia (&pDst, __PKHBT(in2, in1, 16));
write_q15x2_ia (&pDst, __PKHBT(in4, in3, 16));
#else
*pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16));
*pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16));
*pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16));
*pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16));
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A * scale */
/* Scale input and store result in destination buffer. */
*pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16));
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicScale group
*/
@@ -0,0 +1,244 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_scale_q31.c
* Description: Multiplies a Q31 vector by a scalar
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicScale
@{
*/
/**
@brief Multiplies a Q31 vector by a scalar.
@param[in] pSrc points to the input vector
@param[in] scaleFract fractional portion of the scale value
@param[in] shift number of bits to shift the result by
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.31 format.
These are multiplied to yield a 2.62 intermediate result and this is shifted with saturation to 1.31 format.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_scale_q31(
const q31_t * pSrc,
q31_t scaleFract,
int8_t shift,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q31x4_t vecSrc;
q31x4_t vecDst;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
/*
* C = A * scale
* Scale the input and then store the result in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vecDst = vmulhq(vecSrc, vdupq_n_s32(scaleFract));
vecDst = vqshlq_r(vecDst, shift + 1);
vst1q(pDst, vecDst);
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 4;
pDst += 4;
}
/*
* tail
*/
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecSrc = vld1q(pSrc);
vecDst = vmulhq(vecSrc, vdupq_n_s32(scaleFract));
vecDst = vqshlq_r(vecDst, shift + 1);
vstrwq_p(pDst, vecDst, p0);
}
}
#else
void arm_scale_q31(
const q31_t *pSrc,
q31_t scaleFract,
int8_t shift,
q31_t *pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
q31_t in, out; /* Temporary variables */
int8_t kShift = shift + 1; /* Shift to apply after scaling */
int8_t sign = (kShift & 0x80);
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
if (sign == 0U)
{
while (blkCnt > 0U)
{
/* C = A * scale */
/* Scale input and store result in destination buffer. */
in = *pSrc++; /* read input from source */
in = ((q63_t) in * scaleFract) >> 32; /* multiply input with scaler value */
out = in << kShift; /* apply shifting */
if (in != (out >> kShift)) /* saturate the result */
out = 0x7FFFFFFF ^ (in >> 31);
*pDst++ = out; /* Store result destination */
in = *pSrc++;
in = ((q63_t) in * scaleFract) >> 32;
out = in << kShift;
if (in != (out >> kShift))
out = 0x7FFFFFFF ^ (in >> 31);
*pDst++ = out;
in = *pSrc++;
in = ((q63_t) in * scaleFract) >> 32;
out = in << kShift;
if (in != (out >> kShift))
out = 0x7FFFFFFF ^ (in >> 31);
*pDst++ = out;
in = *pSrc++;
in = ((q63_t) in * scaleFract) >> 32;
out = in << kShift;
if (in != (out >> kShift))
out = 0x7FFFFFFF ^ (in >> 31);
*pDst++ = out;
/* Decrement loop counter */
blkCnt--;
}
}
else
{
while (blkCnt > 0U)
{
/* C = A * scale */
/* Scale input and store result in destination buffer. */
in = *pSrc++; /* read four inputs from source */
in = ((q63_t) in * scaleFract) >> 32; /* multiply input with scaler value */
out = in >> -kShift; /* apply shifting */
*pDst++ = out; /* Store result destination */
in = *pSrc++;
in = ((q63_t) in * scaleFract) >> 32;
out = in >> -kShift;
*pDst++ = out;
in = *pSrc++;
in = ((q63_t) in * scaleFract) >> 32;
out = in >> -kShift;
*pDst++ = out;
in = *pSrc++;
in = ((q63_t) in * scaleFract) >> 32;
out = in >> -kShift;
*pDst++ = out;
/* Decrement loop counter */
blkCnt--;
}
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
if (sign == 0U)
{
while (blkCnt > 0U)
{
/* C = A * scale */
/* Scale input and store result in destination buffer. */
in = *pSrc++;
in = ((q63_t) in * scaleFract) >> 32;
out = in << kShift;
if (in != (out >> kShift))
out = 0x7FFFFFFF ^ (in >> 31);
*pDst++ = out;
/* Decrement loop counter */
blkCnt--;
}
}
else
{
while (blkCnt > 0U)
{
/* C = A * scale */
/* Scale input and store result in destination buffer. */
in = *pSrc++;
in = ((q63_t) in * scaleFract) >> 32;
out = in >> -kShift;
*pDst++ = out;
/* Decrement loop counter */
blkCnt--;
}
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicScale group
*/
@@ -0,0 +1,186 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_scale_q7.c
* Description: Multiplies a Q7 vector by a scalar
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicScale
@{
*/
/**
@brief Multiplies a Q7 vector by a scalar.
@param[in] pSrc points to the input vector
@param[in] scaleFract fractional portion of the scale value
@param[in] shift number of bits to shift the result by
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.7 format.
These are multiplied to yield a 2.14 intermediate result and this is shifted with saturation to 1.7 format.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_scale_q7(
const q7_t * pSrc,
q7_t scaleFract,
int8_t shift,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q7x16_t vecSrc;
q7x16_t vecDst;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4;
while (blkCnt > 0U)
{
/*
* C = A * scale
* Scale the input and then store the result in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vecDst = vmulhq(vecSrc, vdupq_n_s8(scaleFract));
vecDst = vqshlq_r(vecDst, shift + 1);
vst1q(pDst, vecDst);
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 16;
pDst += 16;
}
/*
* tail
*/
blkCnt = blockSize & 0xF;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp8q(blkCnt);
vecSrc = vld1q(pSrc);
vecDst = vmulhq(vecSrc, vdupq_n_s8(scaleFract));
vecDst = vqshlq_r(vecDst, shift + 1);
vstrbq_p(pDst, vecDst, p0);
}
}
#else
void arm_scale_q7(
const q7_t * pSrc,
q7_t scaleFract,
int8_t shift,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
int8_t kShift = 7 - shift; /* Shift to apply after scaling */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q7_t in1, in2, in3, in4; /* Temporary input variables */
q7_t out1, out2, out3, out4; /* Temporary output variables */
#endif
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A * scale */
#if defined (ARM_MATH_DSP)
/* Reading 4 inputs from memory */
in1 = *pSrc++;
in2 = *pSrc++;
in3 = *pSrc++;
in4 = *pSrc++;
/* Scale inputs and store result in the temporary variable. */
out1 = (q7_t) (__SSAT(((in1) * scaleFract) >> kShift, 8));
out2 = (q7_t) (__SSAT(((in2) * scaleFract) >> kShift, 8));
out3 = (q7_t) (__SSAT(((in3) * scaleFract) >> kShift, 8));
out4 = (q7_t) (__SSAT(((in4) * scaleFract) >> kShift, 8));
/* Pack and store result in destination buffer (in single write) */
write_q7x4_ia (&pDst, __PACKq7(out1, out2, out3, out4));
#else
*pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8));
*pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8));
*pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8));
*pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8));
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A * scale */
/* Scale input and store result in destination buffer. */
*pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8));
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicScale group
*/
@@ -0,0 +1,251 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_shift_q15.c
* Description: Shifts the elements of a Q15 vector by a specified number of bits
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicShift
@{
*/
/**
@brief Shifts the elements of a Q15 vector a specified number of bits
@param[in] pSrc points to the input vector
@param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_shift_q15(
const q15_t * pSrc,
int8_t shiftBits,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q15x8_t vecSrc;
q15x8_t vecDst;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
/*
* C = A (>> or <<) shiftBits
* Shift the input and then store the result in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vecDst = vqshlq_r(vecSrc, shiftBits);
vst1q(pDst, vecDst);
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 8;
pDst += 8;
}
/*
* tail
*/
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecSrc = vld1q(pSrc);
vecDst = vqshlq_r(vecSrc, shiftBits);
vstrhq_p(pDst, vecDst, p0);
}
}
#else
void arm_shift_q15(
const q15_t * pSrc,
int8_t shiftBits,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
uint8_t sign = (shiftBits & 0x80); /* Sign of shiftBits */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q15_t in1, in2; /* Temporary input variables */
#endif
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
/* If the shift value is positive then do right shift else left shift */
if (sign == 0U)
{
while (blkCnt > 0U)
{
/* C = A << shiftBits */
#if defined (ARM_MATH_DSP)
/* read 2 samples from source */
in1 = *pSrc++;
in2 = *pSrc++;
/* Shift the inputs and then store the results in the destination buffer. */
#ifndef ARM_MATH_BIG_ENDIAN
write_q15x2_ia (&pDst, __PKHBT(__SSAT(((q31_t) in1 << shiftBits), 16),
__SSAT(((q31_t) in2 << shiftBits), 16), 16));
#else
write_q15x2_ia (&pDst, __PKHBT(__SSAT(((q31_t) in2 << shiftBits), 16),
__SSAT(((q31_t) in1 << shiftBits), 16), 16));
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
/* read 2 samples from source */
in1 = *pSrc++;
in2 = *pSrc++;
#ifndef ARM_MATH_BIG_ENDIAN
write_q15x2_ia (&pDst, __PKHBT(__SSAT(((q31_t) in1 << shiftBits), 16),
__SSAT(((q31_t) in2 << shiftBits), 16), 16));
#else
write_q15x2_ia (&pDst, __PKHBT(__SSAT(((q31_t) in2 << shiftBits), 16),
__SSAT(((q31_t) in1 << shiftBits), 16), 16));
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
#else
*pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16);
*pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16);
*pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16);
*pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16);
#endif
/* Decrement loop counter */
blkCnt--;
}
}
else
{
while (blkCnt > 0U)
{
/* C = A >> shiftBits */
#if defined (ARM_MATH_DSP)
/* read 2 samples from source */
in1 = *pSrc++;
in2 = *pSrc++;
/* Shift the inputs and then store the results in the destination buffer. */
#ifndef ARM_MATH_BIG_ENDIAN
write_q15x2_ia (&pDst, __PKHBT((in1 >> -shiftBits),
(in2 >> -shiftBits), 16));
#else
write_q15x2_ia (&pDst, __PKHBT((in2 >> -shiftBits),
(in1 >> -shiftBits), 16));
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
/* read 2 samples from source */
in1 = *pSrc++;
in2 = *pSrc++;
#ifndef ARM_MATH_BIG_ENDIAN
write_q15x2_ia (&pDst, __PKHBT((in1 >> -shiftBits),
(in2 >> -shiftBits), 16));
#else
write_q15x2_ia (&pDst, __PKHBT((in2 >> -shiftBits),
(in1 >> -shiftBits), 16));
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
#else
*pDst++ = (*pSrc++ >> -shiftBits);
*pDst++ = (*pSrc++ >> -shiftBits);
*pDst++ = (*pSrc++ >> -shiftBits);
*pDst++ = (*pSrc++ >> -shiftBits);
#endif
/* Decrement loop counter */
blkCnt--;
}
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
/* If the shift value is positive then do right shift else left shift */
if (sign == 0U)
{
while (blkCnt > 0U)
{
/* C = A << shiftBits */
/* Shift input and store result in destination buffer. */
*pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16);
/* Decrement loop counter */
blkCnt--;
}
}
else
{
while (blkCnt > 0U)
{
/* C = A >> shiftBits */
/* Shift input and store result in destination buffer. */
*pDst++ = (*pSrc++ >> -shiftBits);
/* Decrement loop counter */
blkCnt--;
}
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicShift group
*/
@@ -0,0 +1,232 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_shift_q31.c
* Description: Shifts the elements of a Q31 vector by a specified number of bits
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup BasicShift Vector Shift
Shifts the elements of a fixed-point vector by a specified number of bits.
There are separate functions for Q7, Q15, and Q31 data types.
The underlying algorithm used is:
<pre>
pDst[n] = pSrc[n] << shift, 0 <= n < blockSize.
</pre>
If <code>shift</code> is positive then the elements of the vector are shifted to the left.
If <code>shift</code> is negative then the elements of the vector are shifted to the right.
The functions support in-place computation allowing the source and destination
pointers to reference the same memory buffer.
*/
/**
@addtogroup BasicShift
@{
*/
/**
@brief Shifts the elements of a Q31 vector a specified number of bits.
@param[in] pSrc points to the input vector
@param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in the vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_shift_q31(
const q31_t * pSrc,
int8_t shiftBits,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q31x4_t vecSrc;
q31x4_t vecDst;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
/*
* C = A (>> or <<) shiftBits
* Shift the input and then store the result in the destination buffer.
*/
vecSrc = vld1q((q31_t const *) pSrc);
vecDst = vqshlq_r(vecSrc, shiftBits);
vst1q(pDst, vecDst);
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 4;
pDst += 4;
}
/*
* tail
*/
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecSrc = vld1q((q31_t const *) pSrc);
vecDst = vqshlq_r(vecSrc, shiftBits);
vstrwq_p(pDst, vecDst, p0);
}
}
#else
void arm_shift_q31(
const q31_t * pSrc,
int8_t shiftBits,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
uint8_t sign = (shiftBits & 0x80); /* Sign of shiftBits */
#if defined (ARM_MATH_LOOPUNROLL)
q31_t in, out; /* Temporary variables */
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
/* If the shift value is positive then do right shift else left shift */
if (sign == 0U)
{
while (blkCnt > 0U)
{
/* C = A << shiftBits */
/* Shift input and store result in destination buffer. */
in = *pSrc++;
out = in << shiftBits;
if (in != (out >> shiftBits))
out = 0x7FFFFFFF ^ (in >> 31);
*pDst++ = out;
in = *pSrc++;
out = in << shiftBits;
if (in != (out >> shiftBits))
out = 0x7FFFFFFF ^ (in >> 31);
*pDst++ = out;
in = *pSrc++;
out = in << shiftBits;
if (in != (out >> shiftBits))
out = 0x7FFFFFFF ^ (in >> 31);
*pDst++ = out;
in = *pSrc++;
out = in << shiftBits;
if (in != (out >> shiftBits))
out = 0x7FFFFFFF ^ (in >> 31);
*pDst++ = out;
/* Decrement loop counter */
blkCnt--;
}
}
else
{
while (blkCnt > 0U)
{
/* C = A >> shiftBits */
/* Shift input and store results in destination buffer. */
*pDst++ = (*pSrc++ >> -shiftBits);
*pDst++ = (*pSrc++ >> -shiftBits);
*pDst++ = (*pSrc++ >> -shiftBits);
*pDst++ = (*pSrc++ >> -shiftBits);
/* Decrement loop counter */
blkCnt--;
}
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
/* If the shift value is positive then do right shift else left shift */
if (sign == 0U)
{
while (blkCnt > 0U)
{
/* C = A << shiftBits */
/* Shift input and store result in destination buffer. */
*pDst++ = clip_q63_to_q31((q63_t) *pSrc++ << shiftBits);
/* Decrement loop counter */
blkCnt--;
}
}
else
{
while (blkCnt > 0U)
{
/* C = A >> shiftBits */
/* Shift input and store result in destination buffer. */
*pDst++ = (*pSrc++ >> -shiftBits);
/* Decrement loop counter */
blkCnt--;
}
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicShift group
*/
@@ -0,0 +1,225 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_shift_q7.c
* Description: Processing function for the Q7 Shifting
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicShift
@{
*/
/**
@brief Shifts the elements of a Q7 vector a specified number of bits
@param[in] pSrc points to the input vector
@param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par onditions for optimum performance
Input and output buffers should be aligned by 32-bit
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q7 range [0x80 0x7F] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_shift_q7(
const q7_t * pSrc,
int8_t shiftBits,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q7x16_t vecSrc;
q7x16_t vecDst;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4;
while (blkCnt > 0U)
{
/*
* C = A (>> or <<) shiftBits
* Shift the input and then store the result in the destination buffer.
*/
vecSrc = vld1q(pSrc);
vecDst = vqshlq_r(vecSrc, shiftBits);
vst1q(pDst, vecDst);
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrc += 16;
pDst += 16;
}
/*
* tail
*/
blkCnt = blockSize & 0xF;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp8q(blkCnt);
vecSrc = vld1q(pSrc);
vecDst = vqshlq_r(vecSrc, shiftBits);
vstrbq_p(pDst, vecDst, p0);
}
}
#else
void arm_shift_q7(
const q7_t * pSrc,
int8_t shiftBits,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
uint8_t sign = (shiftBits & 0x80); /* Sign of shiftBits */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q7_t in1, in2, in3, in4; /* Temporary input variables */
#endif
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
/* If the shift value is positive then do right shift else left shift */
if (sign == 0U)
{
while (blkCnt > 0U)
{
/* C = A << shiftBits */
#if defined (ARM_MATH_DSP)
/* Read 4 inputs */
in1 = *pSrc++;
in2 = *pSrc++;
in3 = *pSrc++;
in4 = *pSrc++;
/* Pack and store result in destination buffer (in single write) */
write_q7x4_ia (&pDst, __PACKq7(__SSAT(((q15_t) in1 << shiftBits), 8),
__SSAT(((q15_t) in2 << shiftBits), 8),
__SSAT(((q15_t) in3 << shiftBits), 8),
__SSAT(((q15_t) in4 << shiftBits), 8) ));
#else
*pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8);
*pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8);
*pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8);
*pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8);
#endif
/* Decrement loop counter */
blkCnt--;
}
}
else
{
while (blkCnt > 0U)
{
/* C = A >> shiftBits */
#if defined (ARM_MATH_DSP)
/* Read 4 inputs */
in1 = *pSrc++;
in2 = *pSrc++;
in3 = *pSrc++;
in4 = *pSrc++;
/* Pack and store result in destination buffer (in single write) */
write_q7x4_ia (&pDst, __PACKq7((in1 >> -shiftBits),
(in2 >> -shiftBits),
(in3 >> -shiftBits),
(in4 >> -shiftBits) ));
#else
*pDst++ = (*pSrc++ >> -shiftBits);
*pDst++ = (*pSrc++ >> -shiftBits);
*pDst++ = (*pSrc++ >> -shiftBits);
*pDst++ = (*pSrc++ >> -shiftBits);
#endif
/* Decrement loop counter */
blkCnt--;
}
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
/* If the shift value is positive then do right shift else left shift */
if (sign == 0U)
{
while (blkCnt > 0U)
{
/* C = A << shiftBits */
/* Shift input and store result in destination buffer. */
*pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8);
/* Decrement loop counter */
blkCnt--;
}
}
else
{
while (blkCnt > 0U)
{
/* C = A >> shiftBits */
/* Shift input and store result in destination buffer. */
*pDst++ = (*pSrc++ >> -shiftBits);
/* Decrement loop counter */
blkCnt--;
}
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicShift group
*/
@@ -0,0 +1,202 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_sub_f32.c
* Description: Floating-point vector subtraction
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup BasicSub Vector Subtraction
Element-by-element subtraction of two vectors.
<pre>
pDst[n] = pSrcA[n] - pSrcB[n], 0 <= n < blockSize.
</pre>
There are separate functions for floating-point, Q7, Q15, and Q31 data types.
*/
/**
@addtogroup BasicSub
@{
*/
/**
@brief Floating-point vector subtraction.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_sub_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
f32x4_t vec1;
f32x4_t vec2;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A + B */
/* Add and then store the results in the destination buffer. */
vec1 = vld1q(pSrcA);
vec2 = vld1q(pSrcB);
res = vsubq(vec1, vec2);
vst1q(pDst, res);
/* Increment pointers */
pSrcA += 4;
pSrcB += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
if (blkCnt > 0U)
{
/* C = A + B */
mve_pred16_t p0 = vctp32q(blkCnt);
vec1 = vld1q(pSrcA);
vec2 = vld1q(pSrcB);
vstrwq_p(pDst, vsubq(vec1,vec2), p0);
}
}
#else
void arm_sub_f32(
const float32_t * pSrcA,
const float32_t * pSrcB,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
f32x4_t vec1;
f32x4_t vec2;
f32x4_t res;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A - B */
/* Subtract and then store the results in the destination buffer. */
vec1 = vld1q_f32(pSrcA);
vec2 = vld1q_f32(pSrcB);
res = vsubq_f32(vec1, vec2);
vst1q_f32(pDst, res);
/* Increment pointers */
pSrcA += 4;
pSrcB += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 0x3;
#else
#if defined (ARM_MATH_LOOPUNROLL) && !defined(ARM_MATH_AUTOVECTORIZE)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A - B */
/* Subtract and store result in destination buffer. */
*pDst++ = (*pSrcA++) - (*pSrcB++);
*pDst++ = (*pSrcA++) - (*pSrcB++);
*pDst++ = (*pSrcA++) - (*pSrcB++);
*pDst++ = (*pSrcA++) - (*pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
#endif /* #if defined(ARM_MATH_NEON) */
while (blkCnt > 0U)
{
/* C = A - B */
/* Subtract and store result in destination buffer. */
*pDst++ = (*pSrcA++) - (*pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
/**
@} end of BasicSub group
*/
@@ -0,0 +1,75 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_sub_f64.c
* Description: Floating-point vector subtraction
*
* $Date: 13 September 2021
* $Revision: V1.10.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicSub
@{
*/
/**
@brief Floating-point vector subtraction.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_sub_f64(
const float64_t * pSrcA,
const float64_t * pSrcB,
float64_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
while (blkCnt > 0U)
{
/* C = A - B */
/* Subtract and store result in destination buffer. */
*pDst++ = (*pSrcA++) - (*pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
}
/**
@} end of BasicSub group
*/
@@ -0,0 +1,178 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_sub_q15.c
* Description: Q15 vector subtraction
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicSub
@{
*/
/**
@brief Q15 vector subtraction.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_sub_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q15x8_t vecA;
q15x8_t vecB;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
/*
* C = A - B
* Subtract and then store the results in the destination buffer.
*/
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vst1q(pDst, vqsubq(vecA, vecB));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrcA += 8;
pSrcB += 8;
pDst += 8;
}
/*
* tail
*/
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vstrhq_p(pDst, vqsubq(vecA, vecB), p0);
}
}
#else
void arm_sub_q15(
const q15_t * pSrcA,
const q15_t * pSrcB,
q15_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
#if defined (ARM_MATH_DSP)
q31_t inA1, inA2;
q31_t inB1, inB2;
#endif
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A - B */
#if defined (ARM_MATH_DSP)
/* read 2 times 2 samples at a time from sourceA */
inA1 = read_q15x2_ia (&pSrcA);
inA2 = read_q15x2_ia (&pSrcA);
/* read 2 times 2 samples at a time from sourceB */
inB1 = read_q15x2_ia (&pSrcB);
inB2 = read_q15x2_ia (&pSrcB);
/* Subtract and store 2 times 2 samples at a time */
write_q15x2_ia (&pDst, __QSUB16(inA1, inB1));
write_q15x2_ia (&pDst, __QSUB16(inA2, inB2));
#else
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16);
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16);
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16);
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A - B */
/* Subtract and store result in destination buffer. */
#if defined (ARM_MATH_DSP)
*pDst++ = (q15_t) __QSUB16(*pSrcA++, *pSrcB++);
#else
*pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16);
#endif
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicSub group
*/
@@ -0,0 +1,159 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_sub_q31.c
* Description: Q31 vector subtraction
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicSub
@{
*/
/**
@brief Q31 vector subtraction.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_sub_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt;
q31x4_t vecA;
q31x4_t vecB;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
/*
* C = A + B
* Add and then store the results in the destination buffer.
*/
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vst1q(pDst, vqsubq(vecA, vecB));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrcA += 4;
pSrcB += 4;
pDst += 4;
}
/*
* tail
*/
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vstrwq_p(pDst, vqsubq(vecA, vecB), p0);
}
}
#else
void arm_sub_q31(
const q31_t * pSrcA,
const q31_t * pSrcB,
q31_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A - B */
/* Subtract and store result in destination buffer. */
*pDst++ = __QSUB(*pSrcA++, *pSrcB++);
*pDst++ = __QSUB(*pSrcA++, *pSrcB++);
*pDst++ = __QSUB(*pSrcA++, *pSrcB++);
*pDst++ = __QSUB(*pSrcA++, *pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A - B */
/* Subtract and store result in destination buffer. */
*pDst++ = __QSUB(*pSrcA++, *pSrcB++);
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicSub group
*/
@@ -0,0 +1,158 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_sub_q7.c
* Description: Q7 vector subtraction
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup BasicSub
@{
*/
/**
@brief Q7 vector subtraction.
@param[in] pSrcA points to the first input vector
@param[in] pSrcB points to the second input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
@par Scaling and Overflow Behavior
The function uses saturating arithmetic.
Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
*/
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_helium_utils.h"
void arm_sub_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counters */
q7x16_t vecA;
q7x16_t vecB;
/* Compute 16 outputs at a time */
blkCnt = blockSize >> 4;
while (blkCnt > 0U)
{
/*
* C = A - B
* Subtract and then store the results in the destination buffer.
*/
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vst1q(pDst, vqsubq(vecA, vecB));
/*
* Decrement the blockSize loop counter
*/
blkCnt--;
/*
* advance vector source and destination pointers
*/
pSrcA += 16;
pSrcB += 16;
pDst += 16;
}
/*
* tail
*/
blkCnt = blockSize & 0xF;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp8q(blkCnt);
vecA = vld1q(pSrcA);
vecB = vld1q(pSrcB);
vstrbq_p(pDst, vqsubq(vecA, vecB), p0);
}
}
#else
void arm_sub_q7(
const q7_t * pSrcA,
const q7_t * pSrcB,
q7_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A - B */
#if defined (ARM_MATH_DSP)
/* Subtract and store result in destination buffer (4 samples at a time). */
write_q7x4_ia (&pDst, __QSUB8(read_q7x4_ia (&pSrcA), read_q7x4_ia (&pSrcB)));
#else
*pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8);
*pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8);
*pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8);
*pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8);
#endif
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A - B */
/* Subtract and store result in destination buffer. */
*pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8);
/* Decrement loop counter */
blkCnt--;
}
}
#endif /* defined(ARM_MATH_MVEI) */
/**
@} end of BasicSub group
*/
@@ -0,0 +1,137 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_xor_u16.c
* Description: uint16_t bitwise exclusive OR
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@defgroup Xor Vector bitwise exclusive OR
Compute the logical bitwise XOR.
There are separate functions for uint32_t, uint16_t, and uint8_t data types.
*/
/**
@addtogroup Xor
@{
*/
/**
@brief Compute the logical bitwise XOR of two fixed-point vectors.
@param[in] pSrcA points to input vector A
@param[in] pSrcB points to input vector B
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_xor_u16(
const uint16_t * pSrcA,
const uint16_t * pSrcB,
uint16_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
uint16x8_t vecSrcA, vecSrcB;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3;
while (blkCnt > 0U)
{
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vst1q(pDst, veorq_u16(vecSrcA, vecSrcB) );
pSrcA += 8;
pSrcB += 8;
pDst += 8;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 7;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp16q(blkCnt);
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vstrhq_p(pDst, veorq_u16(vecSrcA, vecSrcB), p0);
}
#else
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
uint16x8_t vecA, vecB;
/* Compute 8 outputs at a time */
blkCnt = blockSize >> 3U;
while (blkCnt > 0U)
{
vecA = vld1q_u16(pSrcA);
vecB = vld1q_u16(pSrcB);
vst1q_u16(pDst, veorq_u16(vecA, vecB) );
pSrcA += 8;
pSrcB += 8;
pDst += 8;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 7;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif
while (blkCnt > 0U)
{
*pDst++ = (*pSrcA++)^(*pSrcB++);
/* Decrement the loop counter */
blkCnt--;
}
#endif /* if defined(ARM_MATH_MVEI) */
}
/**
@} end of Xor group
*/
@@ -0,0 +1,129 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_xor_u32.c
* Description: uint32_t bitwise exclusive OR
*
* $Date: 23 April 2021
* $Revision: V1.9.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dsp/basic_math_functions.h"
/**
@ingroup groupMath
*/
/**
@addtogroup Xor
@{
*/
/**
@brief Compute the logical bitwise XOR of two fixed-point vectors.
@param[in] pSrcA points to input vector A
@param[in] pSrcB points to input vector B
@param[out] pDst points to output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_xor_u32(
const uint32_t * pSrcA,
const uint32_t * pSrcB,
uint32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* Loop counter */
#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
uint32x4_t vecSrcA, vecSrcB;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2;
while (blkCnt > 0U)
{
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vst1q(pDst, veorq_u32(vecSrcA, vecSrcB) );
pSrcA += 4;
pSrcB += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 3;
if (blkCnt > 0U)
{
mve_pred16_t p0 = vctp32q(blkCnt);
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vstrwq_p(pDst, veorq_u32(vecSrcA, vecSrcB), p0);
}
#else
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
uint32x4_t vecA, vecB;
/* Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
vecA = vld1q_u32(pSrcA);
vecB = vld1q_u32(pSrcB);
vst1q_u32(pDst, veorq_u32(vecA, vecB) );
pSrcA += 4;
pSrcB += 4;
pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
/* Tail */
blkCnt = blockSize & 3;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif
while (blkCnt > 0U)
{
*pDst++ = (*pSrcA++)^(*pSrcB++);
/* Decrement the loop counter */
blkCnt--;
}
#endif /* if defined(ARM_MATH_MVEI) */
}
/**
@} end of Xor group
*/

Some files were not shown because too many files have changed in this diff Show More